Introduction
Philadelphia has experienced significant demographic and economic
transformations over recent decades, leading to notable implications for
its urban housing market. These shifts have resulted in variations in
median house values, which serve not only as a reflection of the city’s
economic health but also as a proxy for broader social and spatial
dynamics. Increasing median house values may indicate an influx of
higher-income residents or early stages of gentrification, whereas
declining values can be symptomatic of disinvestment and economic
decline. Given these dynamics, accurately forecasting median house
values is vital for urban planners and policymakers who are tasked with
promoting sustainable and equitable urban development.
In our previous study, Ordinary Least Squares (OLS) regression was
used to explore the relationships between median house values, the
dependent variable, and several key socio-economic predictors in
Philadelphia. These predictors included educational attainment, vacancy
rates, the proportion of detached single-family homes, and poverty rate.
All these factors influenced the homes price in different ways.
Although OLS regression provides a foundational understanding of the
relationships between the predictors and the dependent variables, it has
limitations when applied to spatial data. One of the key assumptions of
OLS regression is that observations are independent of each other and
without spatial autocorrelation. However, in spatial data, observations
that are geographically close often exhibit similarity, leading to
spatial autocorrelation and violating the assumption of the OLS. Violate
the assumptions of OLS may lead to biased and inefficient estimates of
the regression coefficients, and incorrect inferences about the
relationships between the predictors and the dependent variable.
To address these limitations, this report employs advanced spatial
regression techniques to predict median house values in Philadelphia. We
use Spatial Lag Regression, Spatial Error
Regression, and Geographically Weighted Regression
(GWR) to account for spatial autocorrelation and spatial
heterogeneity in the data. We examine whether those spatial regression
model could accurate predict the homes price than the Ordinary Least
Squares (OLS) regression models. By utilizing these spatial techniques,
this study aims to improve the accuracy of the initial OLS findings and
provide a more comprehensive understanding of the socio-economic and
spatial factors influencing housing values. These insights will support
more effective policy interventions and urban development strategies
aimed at achieving equitable and sustainable growth in Philadelphia.
Methods
Concept of Spatial Autocorrelation
The First Law of Geography
Spatial autocorrelation describes the degree to which a variable is
correlated with itself across space. It shows the relationship of values
within a single variable at nearby locations, helping in understanding
patterns of spatial distribution and identifying clusters or dispersions
in spatial data. The concept of spatial autocorrelation is rooted in
The First Law of Geography, which states:
“Everything is related to everything else, but near things are
more related than distant things.”
This principle suggests that geographically proximate areas tend to
exhibit similar characteristics due to shared environmental, economic,
or social factors.
Spatial autocorrelation measures how much a variable in one location
is influenced by values in nearby locations. If observations that are
closer to each other in space have related values, spatial
autocorrelation will be positive. While if observations
that are closer to each other have markedly different values, spatial
autocorrelation will be negative.
Moran’s I
Moran’s I is a widely used method for measuring
spatial autocorrelation. The formula for Moran’s I is:
\[
I = \frac{N}{\sum_{i} \sum_{j} w_{ij}} \times \frac{\sum_{i} \sum_{j}
w_{ij} (X_i - \bar{X}) (X_j - \bar{X})}{\sum_{i} (X_i - \bar{X})^2}
\]
where:
- \(I\) is Moran’s I index,
- \(N\) is the total number of
observations (points or areal units),
- \(w_{ij}\) is the spatial weight
between locations \(i\) and \(j\),
- \(x_i\) and \(x_j\) are the variable values at locations
\(i\) and \(j\),
- \(\bar{x}\) is the mean of the
variable.
A Moran’s I value close to +1
indicates strong positive spatial autocorrelation (clusters of similar
values). A value near -1 suggests strong negative
spatial autocorrelation (dispersion). A value near 0
implies no spatial autocorrelation.
Spatial Weight Matrix
When dealing with spatial data, we use spatial weight
matrices to define relationships between observations. Given
\(n\) observations, we construct an
\(n \times n\) matrix that summarizes
all pairwise spatial relationships in the dataset. These matrices are
essential for estimating spatial regression models and calculating
spatial autocorrelation indices.
There are several ways to define spatial relationships within a
weight matrix. Queen Contiguity Matrix assigns a weight
of 1 if two regions share a border or a vertex, otherwise 0.
Rook Contiguity Matrix assigns a weight of 1 if two
regions share only a border, otherwise 0. Distance-based
Matrix assigns weights based on the inverse distance between
observations.
In this report, we use the Queen contiguity weight
matrix, which considers all neighboring regions that share
either a boundary or a vertex.
Although we only use the queen contiguity weight matrix in the
report, statisticians always use multiple spatial weight matrices to
check the robustness of the results. Since different spatial weights can
capture spatial dependencies at various levels of granularity, it can
make sure the results are not merely an artifact of the matrix you’re
using.
Hypothesis Tests for Spatial Autocorrelation
To determine whether spatial autocorrelation is statistically
significant, we conduct a hypothesis test:
Null Hypothesis (\(H_0\)): No spatial
autocorrelation, meaning that the spatial distribution of values follows
a random pattern with no systematic clustering or dispersion. Each
location’s value is independent of the values at neighboring
locations.
Alternative Hypothesis 1 (\(H_{a1}\)): Positive spatial
autocorrelation, meaning that similar values tend to cluster together.
High values are surrounded by other high values, and low values are
surrounded by other low values, forming distinct spatial
patterns.
Alternative Hypothesis 2 (\(H_{a2}\)): Negative spatial
autocorrelation, meaning that similar values tend to disperse rather
than clustered. High values are surrounded by low values and vice versa,
leading to a checkerboard-like spatial distribution.
To test significance, we conduct random shuffling.
Firstly, we randomly shuffle the variable values across spatial
locations multiple times (999 permutations is used in the report). Then,
we compute Moran’s I for each permuted dataset to generate a reference
distribution. We compare the observed Moran’s I to this distribution to
determine if it is extreme, concluding whether the observed clustering
pattern is statistically meaningful rather than occurring by chance.
If the observed Moran’s I falls in the extreme tail of the simulated
distribution, we reject the null hypothesis (H₀) in favor of the
appropriate alternative hypothesis. A p-value less than
0.05 typically indicates significant spatial
autocorrelation.
Local Moran’s I
While global Moran’s I provides a single statistic for the entire
study area, Local Indicators of Spatial Association
(LISA) provides insights into the presence of spatial
autocorrelation at individual locations.
To determine whether local spatial autocorrelation is statistically
significant, we conduct a hypothesis test:
- Null Hypothesis (\(H_0\)): No local spatial
autocorrelation at location \(i\)
(\(I_i \approx 0\)).
- Here, \(I_i\) represents Moran’s I
at location \(i\).
- This implies that the values of the variable at location \(i\) have no significant relationship with
the values of the variable at neighboring locations \(j\).
- Alternative Hypothesis (\(H_a\)): Presence of local spatial
autocorrelation at location \(i\)
(\(I_i \neq 0\)).
- This means that the values at location \(i\) are either very similar to those at
neighboring locations (indicating positive spatial
autocorrelation) or significantly different from nearby values
(indicating negative spatial autocorrelation).
Significance tests for local Moran’s I are conducted using
random shuffling to ensure that detected clusters are
not merely due to random chance. This process follows the same approach
as global Moran’s I but involves randomly reshuffling the values of the
variable across the study area while keeping the value at
location \(i\) constant. By
comparing the observed local Moran’s I to the distribution of values
from these random permutations, statistical significance can be
assessed.
If the observed \(I_i\) is extremely
high or low compared to the reshuffled values, it is considered
significant. The pseudosignificance value is estimated
by noting the rank of the actual \(I_i\) among the permutations. For instance,
if the original \(I_i\) ranks as the
97th highest among 999 permutations, the estimated pseudosignificance is
\(p \approx
0.097\).
Reviews of OLS Regression and Assumptions
Limitation of OLS Regression
To analyze the relationship between socioeconomic factors and median
house values in Philadelphia, we often use OLS (Ordinary Least Squares)
Regression. By examining these relationships, we aim to identify
critical predictors of median housing values throughout Philadelphia and
offer insights for decision-makers and community initiatives. The key
assumptions of OLS regression include:
Linearity assumes that the relationship between
the dependent variable and the predictors is linear.
Independence of Observations assumes that the
observations are independent of each other. There should be no spatial
or temporal or other forms of dependence in the data.
Homoscedasticity assumes that the variance of
the residuals \(\epsilon\) is constant
regardless of the values of each level of the predictors.
Normality of Residuals assumes that the
residuals are normally distributed.
No Multicollinearity assumes that the predictors
are not highly correlated with each other.
No Fewer than 10 Observations per Predictor
assumes that there are at least 10 observations for each predictor in
the model.
In our first assignment, we used OLS regression to access how vacancy
rates, single-family housing percentage, educational attainment, and
poverty rates influence median house values in Philadelphia. All
predictors were statistically significant. The model’s R-squared was
0.66, which indicate the model explain 66% of the variance in house
values.
However, some predictors exhibited non-linear patterns, and spatial
autocorrelation suggested dependence among observations. For OLS
regression, one of the vital assumptions of OLS regression is that
observations are independent of each other. In spatial
data, observations that are geographically close often exhibit
similarity, leading to spatial autocorrelation and violating the
independence assumption. When spatial autocorrelation is present, values
of a variable in nearby areas are related rather than randomly
distributed. We need further test the spatial autocorrelation and key
assumptions of OLS regression in order to improve the model’s accuracy
and reliability.
Furthermore, when data has a spatial component, the assumption of
normality of residuals often fails to hold. In some
cases, spatial autocorrelation does not significantly impact regression
analysis. If the dependent variable exhibits strong spatial
autocorrelation while the error term does not, the regression
coefficients and significance levels remain valid. Additionally, if both
the dependent and independent variables share an identical spatial
pattern, and the spatial dependencies in the dependent variable are
fully explained by those in the independent variable, the residuals may
be spatially independent. However, this is not always the case, and
it is essential to test for spatial autocorrelation in residuals
to ensure the validity of the model.
Test for Sparial Autocorrelation
To test this assumption, spatial autocorrelation of the residuals can
be examined using Moran’s I, which measures whether
residuals are clustered, dispersed, or randomly distributed in space. As
mentioned before, it is first extract the residuals and define a spatial
weights matrix (e.g., Queen or Rook contiguity). Then, Moran’s I is
computed to measure the degree of clustering in residuals, with values
close to +1 indicating positive spatial autocorrelation, -1 indicating
negative autocorrelation, and 0 suggesting randomness.
Another method to test for spatial autocorrelation in OLS residuals
is to regress them on the residuals from nearby
observations. In this report, nearby residuals refer to
residuals from neighboring block groups, as defined by the Queen matrix.
The regression line between the residuals, OLS_RESIDU and
WT_RESIDU (weighted residuals from neighboring groups),
help identify any spatial autocorrelation. The slope
(b) of this regression represents the strength of spatial
dependence. It is calculated by estimating the relationship between the
residuals of one observation and those of its neighbors.
- If b>0, there is positive spatial
autocorrelation, meaning areas with high residuals tend to be near other
areas with high residuals (or low near low).
- If b<0, there is negative spatial
autocorrelation, meaning areas with high residuals are surrounded by
areas with low residuals (and vice versa).
- If b≈0, there is no spatial autocorrelation,
suggesting that the residuals are randomly distributed.
Assumptions Test
In R, there are methods to test other key assumption as well. We will
continue using R for the analysis.
Another key assumption is Homoscedasticity, which
aassume that the variance of the errors (residuals) remains constant
across all levels of the independent variables. In R, we used
Breusch-Pagan Test, Koenker-Bassett
Test(also known as the Studentized Breusch-Pagan Test). and
White Test to detect heteroscedasticity.
- Null hypothesis (H₀): The errors have constant
variance (homoscedasticity).
- Alternative hypothesis (H₁): The errors have
non-constant variance (heteroscedasticity).
If the p-value is less than 0.05, then we can reject the null
hypothesis for the alternate hypothesis of heteroscedasticity.
Another assumption is Normality of Errors, which
assumes that residuals follow a normal distribution—a crucial
requirement for valid hypothesis testing and confidence intervals. In R,
we used Jarque-Bera Test .
- Null hypothesis (H₀): The residuals follow a normal
distribution.
- Alternative hypothesis (H₁): The residuals do not
follow a normal distribution.
The p-value determines whether the residuals follow a normal
distribution. If the p-value is less than 0.05, then we can reject the
Null Hypothesis of normality for the alternative hypothesis of
non-normality.
Spatial Lag and Spatial Error Regression
In this report, we also use R to run spatial lag and spatial error
regressions. Spatial lag regression assumes the value of the dependent
variable at one location is associated with the values of that variable
in nearby locations, defined by weights matrix \(W\), whether rook, queen neighbors, or
within certain distance of one another. In our context, the spatial lag
model is defined as follows:
\[
\text{LNMEDHVAL} = \rho W \times \text{LNMEDHVAL} + \beta_0 + \beta_1
\times \text{PCTVACANT} + \beta_2 \times \text{PCTSINGLES} + \beta_3
\times \text{PCTBACHMOR} + \beta_4 \times \text{LNNBELPOV100} +
\epsilon_i
\] where:
- \(\text{LNMEDHVAL}\) is the logged
median house value,
- \(\rho\) is the spatial
autoregressive coefficient, which measures the influence of neighboring
areas on the median house value,
- \(W\) is the spatial weights matrix
(in this case, the Queen spatial matrix),
- \(W \times \text{LNMEDHVAL}\) is
the spatially lagged dependent variable (house price),
The other term are same as in the OLS regression model, where:
- \(\beta_0\) is the intercept,
- \(\beta_1\), \(\beta_2\), \(\beta_3\), and \(\beta_4\) are the coefficients of the
predictors,
- \(\epsilon_i\) is the error
term.
The spatial error model, on the other hand, assumes that the
residuals of the model are spatially autocorrelated.It assumes that the
residual in one location is associated with residuals at nearby
locations defined by the spatial weights matrix \(W\), in this case the queen spatial matrix.
The spatial error model is defined as follows:
\[
\text{LNMEDHVAL} = \beta_0 + \beta_1 \times \text{PCTVACANT} + \beta_2
\times \text{PCTSINGLES} + \beta_3 \times \text{PCTBACHMOR} + \beta_4
\times \text{LNNBELPOV100} + \lambda W \times \epsilon + u
\]
where:
- \(\lambda\) is the spatial error
coefficient which measure the degree of spatial correlation in the error
term,
- \(W\) is the spatial weights matrix
(in this case, the Queen spatial matrix),
- \(W \times \epsilon\) is the
spatially lagged error term,
- \(u\) is the random noise
term.
The other term is the same as in the OLS regression model, where:
- \(\text{LNMEDHVAL}\) is the logged
transformed median house value,
- \(\beta_0\) is the intercept,
- \(\beta_1\), \(\beta_2\), \(\beta_3\), and \(\beta_4\) are the coefficients of the
predictors.
Both spatial error regression and spatial lag regression require
standard assumptions of OLS regression, including linerarity,
homoscedasticity, and normality of residuals, excepty for the
assumptions of spatial independence among observations. This adjustment
allows the model to account for spatial autocorrelation and spatial
heterogeneity in the data through either the dependent variable (spatial
lag model) or the error term (spatial error model). These two models
minimize spatial patterns in residuals that could lead to biased and
inefficient estimates.
We compare the results of spatial lag and spatial error regression
with the OLS regression to decide whether the two spatial models perform
better than OLS regression based on several criteria: Akaike Information
Criterion (AIC), Schwarz Criterion (SC, also known as Bayesian
Information Criterion, BIC), Log likelihood, and likelihood ratio
test.
The Akaike Information Criterion (AIC) and
Schward Criterion (SC or BIC) are used to compared the
model’s goodness of fit. They work by estimating how much information is
lost when a model is used to represent reality. Essentially, they
balance how accurate the model is against how complicated it is. A lower
AIC or SC score means the model does a better job at this balance.
The Log likelihood is a measure used in the maximum
likelihood for fitting a statistical model to the data and estimating
model parameters. Maximum likelihood picks the values of the parameters
that make the observed data as likely as possible. The higher the log
likelihood, the better the model explains the data.
The Likelihood Ratio Test is used to test whether
adding a spatial dependence to a model (spatial lag or spatial error
model) significantly improves the model’s fit compared to the OLS model.
For this test:
- The null hypothesis (\(H_0\)) state
that the spatial model does not provide a significant better fit than
OLS
- The alternative hypothesis (\(H_a\)) state that that spatial model
provides a significantly better fit than OLS.
To reject the null hypothesis for the alternative hypothesis that the
spatial model provides a significantly better fit than OLS, the
Likelihood Ratio Test should have a p-value is less
than significant level, typically 0.05. Then, we can draw the conclusion
whether the spatial model is better than OLS model. If not, the OLS
model is adequate.
Note: the likelihood ratio test is not used to compare the
spatial lag and spatial error model, but to compare the spatial model
with the OLS model. The Likelihood Ratio test only work if compared
between nested models, meaning that one model is simplified version of
other – complicated model contains all the same parts as the simpler
model, plus extra pieces. The spatial lag model and spatial error model
is not in that case.
Alternatively, we can also compare the spatial models to OLS using
the Moran’s I statistic,which measures the spatial autocorrelation of
the residuals. Moran’s I ranges from -1 to 1, where -1 indicates perfect
dispersion, 0 indicates no spatial autocorrelation, and 1 indicates
perfect correlation. Our goals of using spatial model is to minimize the
spatial autocorrelation of the residuals. If the Moran’s I of the
residuals of the spatial model is closer to 0 than the Moran’s I of the
residuals of the OLS model, then the spatial model is better at
minimizing spatial autocorrelation. We can conclude that the spatial
model is better captures the spatial dependencies in the data than the
OLS model.
Geographically Weighted Regression
Discussion
# a. recreate variable
data<-data%>%
mutate(LNNBELPOV100 = log(1+NBelPov100))
globalmoranMC<-moran.mc(data$LNMEDHVAL, queenlist, nsim=999, alternative="two.sided")
globalmoranMC
##
## Monte-Carlo simulation of Moran I
##
## data: data$LNMEDHVAL
## weights: queenlist
## number of simulations + 1: 1000
##
## statistic = 0.8, observed rank = 1000, p-value <0.0000000000000002
## alternative hypothesis: two.sided
ggplot(data.frame(res = globalmoranMC$res), aes(x = res)) +
geom_histogram(bins = 100, fill = "#283d3b") +
geom_vline(xintercept = globalmoranMC$statistic, color = "#c44536", linetype = 'dashed', size = 1) +
labs(title = "Observed and Permuted Global Moran's I",
subtitle = "Observed Moran's I in Red",
x = "Moran's I",
y = "Count") +
theme_light() +
theme(plot.subtitle = element_text(size = 9,face = "italic"),
plot.title = element_text(size = 12, face = "bold"),
axis.text.x=element_text(size=6),
axis.text.y=element_text(size=6),
axis.title=element_text(size=8))

data1 <- data.frame( LNMEDHVAL = data$LNMEDHVAL, spatial_lag = lag.listw(queenlist, data$LNMEDHVAL))
ggplot(data1, aes(x = LNMEDHVAL, y = spatial_lag)) +
geom_point(color = "#283d3b", alpha = 0.7, size = 0.6) +
geom_smooth(method = "lm", color = "#c44536", se = FALSE) +
labs(title = "Global Moran's I Scatter Plot",
x = "Logged Median House Value",
y = "Spatial Lag of LNMEDHVAL") +
theme_light() +
theme(plot.subtitle = element_text(size = 9,face = "italic"),
plot.title = element_text(size = 12, face = "bold"),
axis.text.x=element_text(size=6),
axis.text.y=element_text(size=6),
axis.title=element_text(size=8))

# d. Local Moran's I (LISA analysis) for LNMEHVAL
lmoran<-localmoran(data$LNMEDHVAL, queenlist)
head(lmoran)
## Ii E.Ii Var.Ii Z.Ii Pr(z != E(Ii))
## 1 5.3520 -0.00304983 1.305146 4.69 0.000002767
## 2 4.4123 -0.00221660 0.759049 5.07 0.000000404
## 3 3.5007 -0.00304983 0.744493 4.06 0.000048927
## 4 2.4445 -0.00084388 0.241005 4.98 0.000000632
## 5 1.8835 -0.00109417 0.625911 2.38 0.017214326
## 6 0.0995 -0.00000161 0.000921 3.28 0.001042454
df.lmoran <-cbind(data, as.data.frame(lmoran))
## ℹ tmap mode set to "plot".
#Obtaining the Local Moran's P-Values (two-sided)
data$lmp <- lmoran[, "Pr(z != E(Ii))"]
data <- st_make_valid(data)
#Creating the LISA Clusters
mp <- moran.plot(as.vector(scale(data$LNMEDHVAL)), queenlist)

#Significance Map and Cluster Map
data$quadrant <- NA
# high-high
data[(mp$x >= 0 & mp$wx >= 0) & (data$lmp <= 0.05), "quadrant"]<- 1
# low-low
data[(mp$x <= 0 & mp$wx <= 0) & (data$lmp <= 0.05), "quadrant"]<- 2
# high-low
data[(mp$x >= 0 & mp$wx <= 0) & (data$lmp <= 0.05), "quadrant"]<- 3
# low-high
data[(mp$x <= 0 & mp$wx >= 0) & (data$lmp <= 0.05), "quadrant"]<- 4
# non-significant
data[(data$lmp > 0.05), "quadrant"] <- 5
# LISA P-Value Map
p_vals <- tm_shape(data) +
tm_polygons(col = "lmp", title = "",
breaks = c(-Inf, 0.001, 0.01, 0.05, Inf),
palette = c("darkblue", "blue", "lightblue", "white")) +
tm_layout(
legend.outside = TRUE,
legend.text.size = 1,
legend.title.size = 1,
fontfamily = "Arial",
title = "LISA P-Value Map",
title.size = 1.2,
frame = FALSE
)
##
## ── tmap v3 code detected ───────────────────────────────────────────────────────
## [v3->v4] `tm_tm_polygons()`: migrate the argument(s) related to the scale of
## the visual variable `fill` namely 'breaks', 'palette' (rename to 'values') to
## fill.scale = tm_scale(<HERE>).
## [v3->v4] `tm_polygons()`: use 'fill' for the fill color of polygons/symbols
## (instead of 'col'), and 'col' for the outlines (instead of 'border.col').
## [v3->v4] `tm_polygons()`: migrate the argument(s) related to the legend of the
## visual variable `fill` namely 'title' to 'fill.legend = tm_legend(<HERE>)'
## [v3->v4] `tm_layout()`: use text.fontfamily instead of fontfamily
## [v3->v4] `tm_layout()`: use `tm_title()` instead of `tm_layout(title = )`
# LISA Cluster Map
clusters <- tm_shape(data) +
tm_fill(col = "quadrant", title = "",
breaks = c(1, 2, 3, 4, 5, 6),
palette = c("red", "blue", "lightpink", "skyblue2", "white"),
labels = c("High-High", "Low-Low", "High-Low", "Low-High", "Non-significant")) +
tm_borders(alpha = 0.5) +
tm_layout(
frame = FALSE,
legend.outside = TRUE,
legend.text.size = 1,
legend.title.size = 1,
fontfamily = "Arial",
title = "LISA Cluster Map",
title.size = 1.2
)
## [v3->v4] `tm_polygons()`: migrate the argument(s) related to the legend of the
## visual variable `fill` namely 'title' to 'fill.legend = tm_legend(<HERE>)'
## [v3->v4] `tm_borders()`: use `fill_alpha` instead of `alpha`.
## [v3->v4] `tm_layout()`: use text.fontfamily instead of fontfamily
## [v3->v4] `tm_layout()`: use `tm_title()` instead of `tm_layout(title = )`


# e. OLS Regression Analysis
reg<-lm(LNMEDHVAL ~ LNNBELPOV+PCTBACHMOR+PCTSINGLES+PCTVACANT, data=data)
summary(reg)
##
## Call:
## lm(formula = LNMEDHVAL ~ LNNBELPOV + PCTBACHMOR + PCTSINGLES +
## PCTVACANT, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.2582 -0.2039 0.0382 0.2174 2.2434
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 11.113778 0.046532 238.84 < 0.0000000000000002 ***
## LNNBELPOV -0.078903 0.008457 -9.33 < 0.0000000000000002 ***
## PCTBACHMOR 0.020910 0.000543 38.49 < 0.0000000000000002 ***
## PCTSINGLES 0.002977 0.000703 4.23 0.000024 ***
## PCTVACANT -0.019156 0.000978 -19.59 < 0.0000000000000002 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.366 on 1715 degrees of freedom
## Multiple R-squared: 0.662, Adjusted R-squared: 0.662
## F-statistic: 841 on 4 and 1715 DF, p-value: <0.0000000000000002
# g. OLS residuals plotted
data$OLS_RESIDU<-rstandard(reg)
data$WT_RESIDU<-sapply(queen, function(x) mean(data$OLS_RESIDU[x]))
OLS.Residuals.Map<-tm_shape(data)+
tm_fill(col='OLS_RESIDU', style='quantile', title='Standardized OLS Residuals',
palette ='Blues')+
tm_layout(frame=FALSE, title = 'Standardised OLS Residuals')
##
## ── tmap v3 code detected ───────────────────────────────────────────────────────
## [v3->v4] `tm_polygons()`: instead of `style = "quantile"`, use fill.scale =
## `tm_scale_intervals()`.
## ℹ Migrate the argument(s) 'style', 'palette' (rename to 'values') to
## 'tm_scale_intervals(<HERE>)'
## [v3->v4] `tm_polygons()`: migrate the argument(s) related to the legend of the
## visual variable `fill` namely 'title' to 'fill.legend = tm_legend(<HERE>)'
## [v3->v4] `tm_layout()`: use `tm_title()` instead of `tm_layout(title = )`
## [cols4all] color palettes: use palettes from the R package cols4all. Run
## `cols4all::c4a_gui()` to explore them. The old palette name "Blues" is named
## "brewer.blues"
## Multiple palettes called "blues" found: "brewer.blues", "matplotlib.blues". The first one, "brewer.blues", is returned.

# scatterplot of OLS_RESIDU by WT_RESIDU
ggplot(data, aes(x = WT_RESIDU, y = OLS_RESIDU)) +
geom_point(color = "blue", alpha = 0.6) +
geom_smooth(method = "lm", se = FALSE, color = "red") +
labs(title = "Scatter Plot of OLS Residuals vs. Weighted Residuals",
x = "Weighted Residuals (WT_RESIDU)",
y = "OLS Residuals (OLS_RESIDU)") +
theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

# Run simple regression of OLS_RESIDU on WT_RESIDU
lm_residuals <- lm(OLS_RESIDU ~ WT_RESIDU, data = data)
summary(lm_residuals)
##
## Call:
## lm(formula = OLS_RESIDU ~ WT_RESIDU, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -5.368 -0.445 0.058 0.462 5.443
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.0128 0.0212 -0.6 0.55
## WT_RESIDU 0.7323 0.0324 22.6 <0.0000000000000002 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.879 on 1718 degrees of freedom
## Multiple R-squared: 0.229, Adjusted R-squared: 0.228
## F-statistic: 510 on 1 and 1718 DF, p-value: <0.0000000000000002
# h. Moran’s I of the OLS regression residuals
#Regressing residuals on their nearest neighbors.
res.lm <- lm(formula=data$OLS_RESIDU ~ data$WT_RESIDU)
summary(res.lm)
##
## Call:
## lm(formula = data$OLS_RESIDU ~ data$WT_RESIDU)
##
## Residuals:
## Min 1Q Median 3Q Max
## -5.368 -0.445 0.058 0.462 5.443
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.0128 0.0212 -0.6 0.55
## data$WT_RESIDU 0.7323 0.0324 22.6 <0.0000000000000002 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.879 on 1718 degrees of freedom
## Multiple R-squared: 0.229, Adjusted R-squared: 0.228
## F-statistic: 510 on 1 and 1718 DF, p-value: <0.0000000000000002
moran.mc(data$OLS_RESIDU, queenlist, 999, alternative="two.sided")
##
## Monte-Carlo simulation of Moran I
##
## data: data$OLS_RESIDU
## weights: queenlist
## number of simulations + 1: 1000
##
## statistic = 0.3, observed rank = 1000, p-value <0.0000000000000002
## alternative hypothesis: two.sided
moran.plot(data$OLS_RESIDU, queenlist)

LS0tCnRpdGxlOiAnTVVTQSA1MDAwIEFzc2lnbm1lbnQgMjogVXNpbmcgR2VvZ3JhcGhpY2FsbHkgV2VpZ2h0ZWQgUmVncmVzc2lvbiwgU3BhdGlhbAogIExhZywgYW5kIFNwYXRpYWwgRXJyb3IgdG8gUHJlZGljdCBNZWRpYW4gSG91c2UgVmFsdWVzIGluIFBoaWxhZGVscGhpYScKYXV0aG9yOiAiWmhhbmNoYW8gWWFuZywgSGFveXUgWmh1LCBLYXZhbmEgUmFqdSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOiBmbGF0bHkKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGNvZGVfZG93bmxvYWQ6IHllcwogICAgbWF0aGpheDogZGVmYXVsdAotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCm9wdGlvbnMoc2NpcGVuPTk5OSkKb3B0aW9ucyhkaWdpdHMgPSAzKQoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc2YpCmxpYnJhcnkodGlkeWNlbnN1cykKbGlicmFyeShrbml0cikKbGlicmFyeShndCkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KGdnY29ycnBsb3QpCmxpYnJhcnkocGF0Y2h3b3JrKQpsaWJyYXJ5KE1BU1MpCmxpYnJhcnkoc3BkZXApCmxpYnJhcnkoUkNvbG9yQnJld2VyKQpsaWJyYXJ5KHNwZGVwKQpsaWJyYXJ5KHNwZ3dyKQpsaWJyYXJ5KHRtYXApCmxpYnJhcnkoc3BhdGlhbHJlZykKbGlicmFyeSh3aGl0ZXN0cmFwKQpsaWJyYXJ5KGxtdGVzdCkKbGlicmFyeSh0c2VyaWVzKQpgYGAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBpbmNsdWRlPSBGQUxTRX0KZGF0YTwtc3RfcmVhZCgiZGF0YS9SZWdyZXNzaW9uRGF0YS5zaHAiKQpgYGAKCiMgSW50cm9kdWN0aW9uCgpQaGlsYWRlbHBoaWEgaGFzIGV4cGVyaWVuY2VkIHNpZ25pZmljYW50IGRlbW9ncmFwaGljIGFuZCBlY29ub21pYyB0cmFuc2Zvcm1hdGlvbnMgb3ZlciByZWNlbnQgZGVjYWRlcywgbGVhZGluZyB0byBub3RhYmxlIGltcGxpY2F0aW9ucyBmb3IgaXRzIHVyYmFuIGhvdXNpbmcgbWFya2V0LiBUaGVzZSBzaGlmdHMgaGF2ZSByZXN1bHRlZCBpbiB2YXJpYXRpb25zIGluIG1lZGlhbiBob3VzZSB2YWx1ZXMsIHdoaWNoIHNlcnZlIG5vdCBvbmx5IGFzIGEgcmVmbGVjdGlvbiBvZiB0aGUgY2l0eeKAmXMgZWNvbm9taWMgaGVhbHRoIGJ1dCBhbHNvIGFzIGEgcHJveHkgZm9yIGJyb2FkZXIgc29jaWFsIGFuZCBzcGF0aWFsIGR5bmFtaWNzLiBJbmNyZWFzaW5nIG1lZGlhbiBob3VzZSB2YWx1ZXMgbWF5IGluZGljYXRlIGFuIGluZmx1eCBvZiBoaWdoZXItaW5jb21lIHJlc2lkZW50cyBvciBlYXJseSBzdGFnZXMgb2YgZ2VudHJpZmljYXRpb24sIHdoZXJlYXMgZGVjbGluaW5nIHZhbHVlcyBjYW4gYmUgc3ltcHRvbWF0aWMgb2YgZGlzaW52ZXN0bWVudCBhbmQgZWNvbm9taWMgZGVjbGluZS4gR2l2ZW4gdGhlc2UgZHluYW1pY3MsIGFjY3VyYXRlbHkgZm9yZWNhc3RpbmcgbWVkaWFuIGhvdXNlIHZhbHVlcyBpcyB2aXRhbCBmb3IgdXJiYW4gcGxhbm5lcnMgYW5kIHBvbGljeW1ha2VycyB3aG8gYXJlIHRhc2tlZCB3aXRoIHByb21vdGluZyBzdXN0YWluYWJsZSBhbmQgZXF1aXRhYmxlIHVyYmFuIGRldmVsb3BtZW50LgoKSW4gb3VyIHByZXZpb3VzIHN0dWR5LCBPcmRpbmFyeSBMZWFzdCBTcXVhcmVzIChPTFMpIHJlZ3Jlc3Npb24gd2FzIHVzZWQgdG8gZXhwbG9yZSB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIG1lZGlhbiBob3VzZSB2YWx1ZXMsIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUsIGFuZCBzZXZlcmFsIGtleSBzb2Npby1lY29ub21pYyBwcmVkaWN0b3JzIGluIFBoaWxhZGVscGhpYS4gVGhlc2UgcHJlZGljdG9ycyBpbmNsdWRlZCBlZHVjYXRpb25hbCBhdHRhaW5tZW50LCB2YWNhbmN5IHJhdGVzLCB0aGUgcHJvcG9ydGlvbiBvZiBkZXRhY2hlZCBzaW5nbGUtZmFtaWx5IGhvbWVzLCBhbmQgcG92ZXJ0eSByYXRlLiBBbGwgdGhlc2UgZmFjdG9ycyBpbmZsdWVuY2VkIHRoZSBob21lcyBwcmljZSBpbiBkaWZmZXJlbnQgd2F5cy4gCgpBbHRob3VnaCBPTFMgcmVncmVzc2lvbiBwcm92aWRlcyBhIGZvdW5kYXRpb25hbCB1bmRlcnN0YW5kaW5nIG9mIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gdGhlIHByZWRpY3RvcnMgYW5kIHRoZSBkZXBlbmRlbnQgdmFyaWFibGVzLCBpdCBoYXMgbGltaXRhdGlvbnMgd2hlbiBhcHBsaWVkIHRvIHNwYXRpYWwgZGF0YS4gT25lIG9mIHRoZSBrZXkgYXNzdW1wdGlvbnMgb2YgT0xTIHJlZ3Jlc3Npb24gaXMgdGhhdCBvYnNlcnZhdGlvbnMgYXJlIGluZGVwZW5kZW50IG9mIGVhY2ggb3RoZXIgYW5kIHdpdGhvdXQgc3BhdGlhbCBhdXRvY29ycmVsYXRpb24uIEhvd2V2ZXIsIGluIHNwYXRpYWwgZGF0YSwgb2JzZXJ2YXRpb25zIHRoYXQgYXJlIGdlb2dyYXBoaWNhbGx5IGNsb3NlIG9mdGVuIGV4aGliaXQgc2ltaWxhcml0eSwgbGVhZGluZyB0byBzcGF0aWFsIGF1dG9jb3JyZWxhdGlvbiBhbmQgdmlvbGF0aW5nIHRoZSBhc3N1bXB0aW9uIG9mIHRoZSBPTFMuIFZpb2xhdGUgdGhlIGFzc3VtcHRpb25zIG9mIE9MUyBtYXkgbGVhZCB0byBiaWFzZWQgYW5kIGluZWZmaWNpZW50IGVzdGltYXRlcyBvZiB0aGUgcmVncmVzc2lvbiBjb2VmZmljaWVudHMsIGFuZCBpbmNvcnJlY3QgaW5mZXJlbmNlcyBhYm91dCB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRoZSBwcmVkaWN0b3JzIGFuZCB0aGUgZGVwZW5kZW50IHZhcmlhYmxlLgoKVG8gYWRkcmVzcyB0aGVzZSBsaW1pdGF0aW9ucywgdGhpcyByZXBvcnQgZW1wbG95cyBhZHZhbmNlZCBzcGF0aWFsIHJlZ3Jlc3Npb24gdGVjaG5pcXVlcyB0byBwcmVkaWN0IG1lZGlhbiBob3VzZSB2YWx1ZXMgaW4gUGhpbGFkZWxwaGlhLiBXZSB1c2UgKipTcGF0aWFsIExhZyBSZWdyZXNzaW9uKiosICoqU3BhdGlhbCBFcnJvciBSZWdyZXNzaW9uKiosIGFuZCAqKkdlb2dyYXBoaWNhbGx5IFdlaWdodGVkIFJlZ3Jlc3Npb24gKEdXUikqKiB0byBhY2NvdW50IGZvciBzcGF0aWFsIGF1dG9jb3JyZWxhdGlvbiBhbmQgc3BhdGlhbCBoZXRlcm9nZW5laXR5IGluIHRoZSBkYXRhLiBXZSBleGFtaW5lIHdoZXRoZXIgdGhvc2Ugc3BhdGlhbCByZWdyZXNzaW9uIG1vZGVsIGNvdWxkIGFjY3VyYXRlIHByZWRpY3QgdGhlIGhvbWVzIHByaWNlIHRoYW4gdGhlIE9yZGluYXJ5IExlYXN0IFNxdWFyZXMgKE9MUykgcmVncmVzc2lvbiBtb2RlbHMuIEJ5IHV0aWxpemluZyB0aGVzZSBzcGF0aWFsIHRlY2huaXF1ZXMsIHRoaXMgc3R1ZHkgYWltcyB0byBpbXByb3ZlIHRoZSBhY2N1cmFjeSBvZiB0aGUgaW5pdGlhbCBPTFMgZmluZGluZ3MgYW5kIHByb3ZpZGUgYSBtb3JlIGNvbXByZWhlbnNpdmUgdW5kZXJzdGFuZGluZyBvZiB0aGUgc29jaW8tZWNvbm9taWMgYW5kIHNwYXRpYWwgZmFjdG9ycyBpbmZsdWVuY2luZyBob3VzaW5nIHZhbHVlcy4gVGhlc2UgaW5zaWdodHMgd2lsbCBzdXBwb3J0IG1vcmUgZWZmZWN0aXZlIHBvbGljeSBpbnRlcnZlbnRpb25zIGFuZCB1cmJhbiBkZXZlbG9wbWVudCBzdHJhdGVnaWVzIGFpbWVkIGF0IGFjaGlldmluZyBlcXVpdGFibGUgYW5kIHN1c3RhaW5hYmxlIGdyb3d0aCBpbiBQaGlsYWRlbHBoaWEuCgojIE1ldGhvZHMKCiMjIENvbmNlcHQgb2YgU3BhdGlhbCBBdXRvY29ycmVsYXRpb24KCiMjIyBUaGUgRmlyc3QgTGF3IG9mIEdlb2dyYXBoeQoKU3BhdGlhbCBhdXRvY29ycmVsYXRpb24gZGVzY3JpYmVzIHRoZSBkZWdyZWUgdG8gd2hpY2ggYSB2YXJpYWJsZSBpcyBjb3JyZWxhdGVkIHdpdGggaXRzZWxmIGFjcm9zcyBzcGFjZS4gSXQgc2hvd3MgdGhlIHJlbGF0aW9uc2hpcCBvZiB2YWx1ZXMgd2l0aGluIGEgc2luZ2xlIHZhcmlhYmxlIGF0IG5lYXJieSBsb2NhdGlvbnMsIGhlbHBpbmcgaW4gdW5kZXJzdGFuZGluZyBwYXR0ZXJucyBvZiBzcGF0aWFsIGRpc3RyaWJ1dGlvbiBhbmQgaWRlbnRpZnlpbmcgY2x1c3RlcnMgb3IgZGlzcGVyc2lvbnMgaW4gc3BhdGlhbCBkYXRhLiBUaGUgY29uY2VwdCBvZiBzcGF0aWFsIGF1dG9jb3JyZWxhdGlvbiBpcyByb290ZWQgaW4gKipUaGUgRmlyc3QgTGF3IG9mIEdlb2dyYXBoeSoqLCB3aGljaCBzdGF0ZXM6Cgo+ICoiRXZlcnl0aGluZyBpcyByZWxhdGVkIHRvIGV2ZXJ5dGhpbmcgZWxzZSwgYnV0IG5lYXIgdGhpbmdzIGFyZSBtb3JlIHJlbGF0ZWQgdGhhbiBkaXN0YW50IHRoaW5ncy4iKgoKVGhpcyBwcmluY2lwbGUgc3VnZ2VzdHMgdGhhdCBnZW9ncmFwaGljYWxseSBwcm94aW1hdGUgYXJlYXMgdGVuZCB0byBleGhpYml0IHNpbWlsYXIgY2hhcmFjdGVyaXN0aWNzIGR1ZSB0byBzaGFyZWQgZW52aXJvbm1lbnRhbCwgZWNvbm9taWMsIG9yIHNvY2lhbCBmYWN0b3JzLgoKU3BhdGlhbCBhdXRvY29ycmVsYXRpb24gbWVhc3VyZXMgaG93IG11Y2ggYSB2YXJpYWJsZSBpbiBvbmUgbG9jYXRpb24gaXMgaW5mbHVlbmNlZCBieSB2YWx1ZXMgaW4gbmVhcmJ5IGxvY2F0aW9ucy4gSWYgb2JzZXJ2YXRpb25zIHRoYXQgYXJlIGNsb3NlciB0byBlYWNoIG90aGVyIGluIHNwYWNlIGhhdmUgcmVsYXRlZCB2YWx1ZXMsIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uIHdpbGwgYmUgKipwb3NpdGl2ZSoqLiBXaGlsZSBpZiBvYnNlcnZhdGlvbnMgdGhhdCBhcmUgY2xvc2VyIHRvIGVhY2ggb3RoZXIgaGF2ZSBtYXJrZWRseSBkaWZmZXJlbnQgdmFsdWVzLCBzcGF0aWFsIGF1dG9jb3JyZWxhdGlvbiB3aWxsIGJlICoqbmVnYXRpdmUqKi4KCiMjIyBNb3JhbuKAmXMgSQoKKipNb3JhbuKAmXMgSSoqIGlzIGEgd2lkZWx5IHVzZWQgbWV0aG9kIGZvciBtZWFzdXJpbmcgc3BhdGlhbCBhdXRvY29ycmVsYXRpb24uIFRoZSBmb3JtdWxhIGZvciBNb3JhbuKAmXMgSSBpczoKCiQkCkkgPSBcZnJhY3tOfXtcc3VtX3tpfSBcc3VtX3tqfSB3X3tpan19IFx0aW1lcyBcZnJhY3tcc3VtX3tpfSBcc3VtX3tqfSB3X3tpan0gKFhfaSAtIFxiYXJ7WH0pIChYX2ogLSBcYmFye1h9KX17XHN1bV97aX0gKFhfaSAtIFxiYXJ7WH0pXjJ9CiQkCgp3aGVyZToKCi0gXCggSSBcKSBpcyBNb3JhbuKAmXMgSSBpbmRleCwKLSBcKCBOIFwpIGlzIHRoZSB0b3RhbCBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zIChwb2ludHMgb3IgYXJlYWwgdW5pdHMpLAotIFwoIHdfe2lqfSBcKSBpcyB0aGUgc3BhdGlhbCB3ZWlnaHQgYmV0d2VlbiBsb2NhdGlvbnMgXCggaSBcKSBhbmQgXCggaiBcKSwKLSBcKCB4X2kgXCkgYW5kIFwoIHhfaiBcKSBhcmUgdGhlIHZhcmlhYmxlIHZhbHVlcyBhdCBsb2NhdGlvbnMgXCggaSBcKSBhbmQgXCggaiBcKSwKLSBcKCBcYmFye3h9IFwpIGlzIHRoZSBtZWFuIG9mIHRoZSB2YXJpYWJsZS4KCkEgKipNb3JhbuKAmXMgSSoqIHZhbHVlIGNsb3NlIHRvICoqKzEqKiBpbmRpY2F0ZXMgc3Ryb25nIHBvc2l0aXZlIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uIChjbHVzdGVycyBvZiBzaW1pbGFyIHZhbHVlcykuIEEgdmFsdWUgbmVhciAqKi0xKiogc3VnZ2VzdHMgc3Ryb25nIG5lZ2F0aXZlIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uIChkaXNwZXJzaW9uKS4gQSB2YWx1ZSBuZWFyICoqMCoqIGltcGxpZXMgbm8gc3BhdGlhbCBhdXRvY29ycmVsYXRpb24uCgojIyMgU3BhdGlhbCBXZWlnaHQgTWF0cml4CgpXaGVuIGRlYWxpbmcgd2l0aCBzcGF0aWFsIGRhdGEsIHdlIHVzZSAqKnNwYXRpYWwgd2VpZ2h0IG1hdHJpY2VzKiogdG8gZGVmaW5lIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBvYnNlcnZhdGlvbnMuIEdpdmVuIFwoIG4gXCkgb2JzZXJ2YXRpb25zLCB3ZSBjb25zdHJ1Y3QgYW4gXCggbiBcdGltZXMgbiBcKSBtYXRyaXggdGhhdCBzdW1tYXJpemVzIGFsbCBwYWlyd2lzZSBzcGF0aWFsIHJlbGF0aW9uc2hpcHMgaW4gdGhlIGRhdGFzZXQuIFRoZXNlIG1hdHJpY2VzIGFyZSBlc3NlbnRpYWwgZm9yIGVzdGltYXRpbmcgc3BhdGlhbCByZWdyZXNzaW9uIG1vZGVscyBhbmQgY2FsY3VsYXRpbmcgc3BhdGlhbCBhdXRvY29ycmVsYXRpb24gaW5kaWNlcy4KClRoZXJlIGFyZSBzZXZlcmFsIHdheXMgdG8gZGVmaW5lIHNwYXRpYWwgcmVsYXRpb25zaGlwcyB3aXRoaW4gYSB3ZWlnaHQgbWF0cml4LiAqKlF1ZWVuIENvbnRpZ3VpdHkgTWF0cml4KiogYXNzaWducyBhIHdlaWdodCBvZiAxIGlmIHR3byByZWdpb25zIHNoYXJlIGEgYm9yZGVyIG9yIGEgdmVydGV4LCBvdGhlcndpc2UgMC4gKipSb29rIENvbnRpZ3VpdHkgTWF0cml4KiogYXNzaWducyBhIHdlaWdodCBvZiAxIGlmIHR3byByZWdpb25zIHNoYXJlIG9ubHkgYSBib3JkZXIsIG90aGVyd2lzZSAwLiAqKkRpc3RhbmNlLWJhc2VkIE1hdHJpeCoqIGFzc2lnbnMgd2VpZ2h0cyBiYXNlZCBvbiB0aGUgaW52ZXJzZSBkaXN0YW5jZSBiZXR3ZWVuIG9ic2VydmF0aW9ucy4KCkluIHRoaXMgcmVwb3J0LCB3ZSB1c2UgdGhlICoqUXVlZW4gY29udGlndWl0eSB3ZWlnaHQgbWF0cml4KiosIHdoaWNoIGNvbnNpZGVycyBhbGwgbmVpZ2hib3JpbmcgcmVnaW9ucyB0aGF0IHNoYXJlIGVpdGhlciBhIGJvdW5kYXJ5IG9yIGEgdmVydGV4LgoKQWx0aG91Z2ggd2Ugb25seSB1c2UgdGhlIHF1ZWVuIGNvbnRpZ3VpdHkgd2VpZ2h0IG1hdHJpeCBpbiB0aGUgcmVwb3J0LCBzdGF0aXN0aWNpYW5zIGFsd2F5cyB1c2UgbXVsdGlwbGUgc3BhdGlhbCB3ZWlnaHQgbWF0cmljZXMgdG8gY2hlY2sgdGhlIHJvYnVzdG5lc3Mgb2YgdGhlIHJlc3VsdHMuIFNpbmNlIGRpZmZlcmVudCBzcGF0aWFsIHdlaWdodHMgY2FuIGNhcHR1cmUgc3BhdGlhbCBkZXBlbmRlbmNpZXMgYXQgdmFyaW91cyBsZXZlbHMgb2YgZ3JhbnVsYXJpdHksIGl0IGNhbiBtYWtlIHN1cmUgdGhlIHJlc3VsdHMgYXJlIG5vdCBtZXJlbHkgYW4gYXJ0aWZhY3Qgb2YgdGhlIG1hdHJpeCB5b3XigJlyZSB1c2luZy4KCiMjIyBIeXBvdGhlc2lzIFRlc3RzIGZvciBTcGF0aWFsIEF1dG9jb3JyZWxhdGlvbiAKClRvIGRldGVybWluZSB3aGV0aGVyIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQsIHdlIGNvbmR1Y3QgYSBoeXBvdGhlc2lzIHRlc3Q6CgotICoqTnVsbCBIeXBvdGhlc2lzIChcKEhfMFwpKSoqOiBObyBzcGF0aWFsIGF1dG9jb3JyZWxhdGlvbiwgbWVhbmluZyB0aGF0IHRoZSBzcGF0aWFsIGRpc3RyaWJ1dGlvbiBvZiB2YWx1ZXMgZm9sbG93cyBhIHJhbmRvbSBwYXR0ZXJuIHdpdGggbm8gc3lzdGVtYXRpYyBjbHVzdGVyaW5nIG9yIGRpc3BlcnNpb24uIEVhY2ggbG9jYXRpb24ncyB2YWx1ZSBpcyBpbmRlcGVuZGVudCBvZiB0aGUgdmFsdWVzIGF0IG5laWdoYm9yaW5nIGxvY2F0aW9ucy4KCi0gKipBbHRlcm5hdGl2ZSBIeXBvdGhlc2lzIDEgKFwoSF97YTF9XCkpKio6IFBvc2l0aXZlIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uLCBtZWFuaW5nIHRoYXQgc2ltaWxhciB2YWx1ZXMgdGVuZCB0byBjbHVzdGVyIHRvZ2V0aGVyLiBIaWdoIHZhbHVlcyBhcmUgc3Vycm91bmRlZCBieSBvdGhlciBoaWdoIHZhbHVlcywgYW5kIGxvdyB2YWx1ZXMgYXJlIHN1cnJvdW5kZWQgYnkgb3RoZXIgbG93IHZhbHVlcywgZm9ybWluZyBkaXN0aW5jdCBzcGF0aWFsIHBhdHRlcm5zLgoKLSAqKkFsdGVybmF0aXZlIEh5cG90aGVzaXMgMiAoXChIX3thMn1cKSkqKjogTmVnYXRpdmUgc3BhdGlhbCBhdXRvY29ycmVsYXRpb24sIG1lYW5pbmcgdGhhdCBzaW1pbGFyIHZhbHVlcyB0ZW5kIHRvIGRpc3BlcnNlIHJhdGhlciB0aGFuIGNsdXN0ZXJlZC4gSGlnaCB2YWx1ZXMgYXJlIHN1cnJvdW5kZWQgYnkgbG93IHZhbHVlcyBhbmQgdmljZSB2ZXJzYSwgbGVhZGluZyB0byBhIGNoZWNrZXJib2FyZC1saWtlIHNwYXRpYWwgZGlzdHJpYnV0aW9uLgoKClRvIHRlc3Qgc2lnbmlmaWNhbmNlLCB3ZSBjb25kdWN0ICoqcmFuZG9tIHNodWZmbGluZyoqLiBGaXJzdGx5LCB3ZSByYW5kb21seSBzaHVmZmxlIHRoZSB2YXJpYWJsZSB2YWx1ZXMgYWNyb3NzIHNwYXRpYWwgbG9jYXRpb25zIG11bHRpcGxlIHRpbWVzICg5OTkgcGVybXV0YXRpb25zIGlzIHVzZWQgaW4gdGhlIHJlcG9ydCkuIFRoZW4sIHdlIGNvbXB1dGUgTW9yYW7igJlzIEkgZm9yIGVhY2ggcGVybXV0ZWQgZGF0YXNldCB0byBnZW5lcmF0ZSBhIHJlZmVyZW5jZSBkaXN0cmlidXRpb24uIFdlIGNvbXBhcmUgdGhlIG9ic2VydmVkIE1vcmFu4oCZcyBJIHRvIHRoaXMgZGlzdHJpYnV0aW9uIHRvIGRldGVybWluZSBpZiBpdCBpcyBleHRyZW1lLCBjb25jbHVkaW5nIHdoZXRoZXIgdGhlIG9ic2VydmVkIGNsdXN0ZXJpbmcgcGF0dGVybiBpcyBzdGF0aXN0aWNhbGx5IG1lYW5pbmdmdWwgcmF0aGVyIHRoYW4gb2NjdXJyaW5nIGJ5IGNoYW5jZS4KCklmIHRoZSBvYnNlcnZlZCBNb3JhbuKAmXMgSSBmYWxscyBpbiB0aGUgZXh0cmVtZSB0YWlsIG9mIHRoZSBzaW11bGF0ZWQgZGlzdHJpYnV0aW9uLCB3ZSByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyAoSOKCgCkgaW4gZmF2b3Igb2YgdGhlIGFwcHJvcHJpYXRlIGFsdGVybmF0aXZlIGh5cG90aGVzaXMuIEEgcC12YWx1ZSBsZXNzIHRoYW4gKiowLjA1KiogdHlwaWNhbGx5IGluZGljYXRlcyBzaWduaWZpY2FudCBzcGF0aWFsIGF1dG9jb3JyZWxhdGlvbi4KCiMjIyBMb2NhbCBNb3JhbuKAmXMgSQoKV2hpbGUgZ2xvYmFsIE1vcmFu4oCZcyBJIHByb3ZpZGVzIGEgc2luZ2xlIHN0YXRpc3RpYyBmb3IgdGhlIGVudGlyZSBzdHVkeSBhcmVhLCAqKkxvY2FsIEluZGljYXRvcnMgb2YgU3BhdGlhbCBBc3NvY2lhdGlvbiAoTElTQSkqKiBwcm92aWRlcyBpbnNpZ2h0cyBpbnRvIHRoZSBwcmVzZW5jZSBvZiBzcGF0aWFsIGF1dG9jb3JyZWxhdGlvbiBhdCAqKmluZGl2aWR1YWwqKiBsb2NhdGlvbnMuCgpUbyBkZXRlcm1pbmUgd2hldGhlciBsb2NhbCBzcGF0aWFsIGF1dG9jb3JyZWxhdGlvbiBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LCB3ZSBjb25kdWN0IGEgaHlwb3RoZXNpcyB0ZXN0OgoKLSAqKk51bGwgSHlwb3RoZXNpcyAoXChIXzBcKSkqKjogTm8gbG9jYWwgc3BhdGlhbCBhdXRvY29ycmVsYXRpb24gYXQgbG9jYXRpb24gXChpXCkgKFwoSV9pIFxhcHByb3ggMFwpKS4KICAtIEhlcmUsIFwoSV9pXCkgcmVwcmVzZW50cyBNb3JhbuKAmXMgSSBhdCBsb2NhdGlvbiBcKGlcKS4KICAtIFRoaXMgaW1wbGllcyB0aGF0IHRoZSB2YWx1ZXMgb2YgdGhlIHZhcmlhYmxlIGF0IGxvY2F0aW9uIFwoaVwpIGhhdmUgbm8gc2lnbmlmaWNhbnQgcmVsYXRpb25zaGlwIHdpdGggdGhlIHZhbHVlcyBvZiB0aGUgdmFyaWFibGUgYXQgbmVpZ2hib3JpbmcgbG9jYXRpb25zIFwoalwpLgoKLSAqKkFsdGVybmF0aXZlIEh5cG90aGVzaXMgKFwoSF9hXCkpKio6IFByZXNlbmNlIG9mIGxvY2FsIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uIGF0IGxvY2F0aW9uIFwoaVwpIChcKElfaSBcbmVxIDBcKSkuCiAgLSBUaGlzIG1lYW5zIHRoYXQgdGhlIHZhbHVlcyBhdCBsb2NhdGlvbiBcKGlcKSBhcmUgZWl0aGVyIHZlcnkgc2ltaWxhciB0byB0aG9zZSBhdCBuZWlnaGJvcmluZyBsb2NhdGlvbnMgKGluZGljYXRpbmcgKipwb3NpdGl2ZSBzcGF0aWFsIGF1dG9jb3JyZWxhdGlvbioqKSBvciBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBmcm9tIG5lYXJieSB2YWx1ZXMgKGluZGljYXRpbmcgKipuZWdhdGl2ZSBzcGF0aWFsIGF1dG9jb3JyZWxhdGlvbioqKS4KCgpTaWduaWZpY2FuY2UgdGVzdHMgZm9yIGxvY2FsIE1vcmFu4oCZcyBJIGFyZSBjb25kdWN0ZWQgdXNpbmcgKipyYW5kb20gc2h1ZmZsaW5nKiogdG8gZW5zdXJlIHRoYXQgZGV0ZWN0ZWQgY2x1c3RlcnMgYXJlIG5vdCBtZXJlbHkgZHVlIHRvIHJhbmRvbSBjaGFuY2UuIFRoaXMgcHJvY2VzcyBmb2xsb3dzIHRoZSBzYW1lIGFwcHJvYWNoIGFzIGdsb2JhbCBNb3JhbuKAmXMgSSBidXQgaW52b2x2ZXMgcmFuZG9tbHkgcmVzaHVmZmxpbmcgdGhlIHZhbHVlcyBvZiB0aGUgdmFyaWFibGUgYWNyb3NzIHRoZSBzdHVkeSBhcmVhIHdoaWxlICoqa2VlcGluZyB0aGUgdmFsdWUgYXQgbG9jYXRpb24gXChpXCkgY29uc3RhbnQqKi4gQnkgY29tcGFyaW5nIHRoZSBvYnNlcnZlZCBsb2NhbCBNb3JhbuKAmXMgSSB0byB0aGUgZGlzdHJpYnV0aW9uIG9mIHZhbHVlcyBmcm9tIHRoZXNlIHJhbmRvbSBwZXJtdXRhdGlvbnMsIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSBjYW4gYmUgYXNzZXNzZWQuCgpJZiB0aGUgb2JzZXJ2ZWQgXChJX2lcKSBpcyBleHRyZW1lbHkgaGlnaCBvciBsb3cgY29tcGFyZWQgdG8gdGhlIHJlc2h1ZmZsZWQgdmFsdWVzLCBpdCBpcyBjb25zaWRlcmVkIHNpZ25pZmljYW50LiBUaGUgKipwc2V1ZG9zaWduaWZpY2FuY2UgdmFsdWUqKiBpcyBlc3RpbWF0ZWQgYnkgbm90aW5nIHRoZSByYW5rIG9mIHRoZSBhY3R1YWwgXChJX2lcKSBhbW9uZyB0aGUgcGVybXV0YXRpb25zLiBGb3IgaW5zdGFuY2UsIGlmIHRoZSBvcmlnaW5hbCBcKElfaVwpIHJhbmtzIGFzIHRoZSA5N3RoIGhpZ2hlc3QgYW1vbmcgOTk5IHBlcm11dGF0aW9ucywgdGhlIGVzdGltYXRlZCBwc2V1ZG9zaWduaWZpY2FuY2UgaXMgKipcKHAgXGFwcHJveCAwLjA5N1wpKiouCgoKIyMgUmV2aWV3cyBvZiBPTFMgUmVncmVzc2lvbiBhbmQgQXNzdW1wdGlvbnMKCiMjIyBMaW1pdGF0aW9uIG9mIE9MUyBSZWdyZXNzaW9uCgpUbyBhbmFseXplIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBzb2Npb2Vjb25vbWljIGZhY3RvcnMgYW5kIG1lZGlhbiBob3VzZSB2YWx1ZXMgaW4gUGhpbGFkZWxwaGlhLCB3ZSBvZnRlbiB1c2UgT0xTIChPcmRpbmFyeSBMZWFzdCBTcXVhcmVzKSBSZWdyZXNzaW9uLiBCeSBleGFtaW5pbmcgdGhlc2UgcmVsYXRpb25zaGlwcywgd2UgYWltIHRvIGlkZW50aWZ5IGNyaXRpY2FsIHByZWRpY3RvcnMgb2YgbWVkaWFuIGhvdXNpbmcgdmFsdWVzIHRocm91Z2hvdXQgUGhpbGFkZWxwaGlhIGFuZCBvZmZlciBpbnNpZ2h0cyBmb3IgZGVjaXNpb24tbWFrZXJzIGFuZCBjb21tdW5pdHkgaW5pdGlhdGl2ZXMuIFRoZSBrZXkgYXNzdW1wdGlvbnMgb2YgT0xTIHJlZ3Jlc3Npb24gaW5jbHVkZToKCi0gKipMaW5lYXJpdHkqKiBhc3N1bWVzIHRoYXQgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUgYW5kIHRoZSBwcmVkaWN0b3JzIGlzIGxpbmVhci4gCgotICAqKkluZGVwZW5kZW5jZSBvZiBPYnNlcnZhdGlvbnMqKiBhc3N1bWVzIHRoYXQgdGhlIG9ic2VydmF0aW9ucyBhcmUgaW5kZXBlbmRlbnQgb2YgZWFjaCBvdGhlci4gVGhlcmUgc2hvdWxkIGJlIG5vIHNwYXRpYWwgb3IgdGVtcG9yYWwgb3Igb3RoZXIgZm9ybXMgb2YgZGVwZW5kZW5jZSBpbiB0aGUgZGF0YS4KCi0gKipIb21vc2NlZGFzdGljaXR5KiogYXNzdW1lcyB0aGF0IHRoZSB2YXJpYW5jZSBvZiB0aGUgcmVzaWR1YWxzIFwoXGVwc2lsb25cKSBpcyBjb25zdGFudCByZWdhcmRsZXNzIG9mIHRoZSB2YWx1ZXMgb2YgZWFjaCBsZXZlbCBvZiB0aGUgcHJlZGljdG9ycy4gCgotICoqTm9ybWFsaXR5IG9mIFJlc2lkdWFscyoqIGFzc3VtZXMgdGhhdCB0aGUgcmVzaWR1YWxzIGFyZSBub3JtYWxseSBkaXN0cmlidXRlZC4gCgotICoqTm8gTXVsdGljb2xsaW5lYXJpdHkqKiBhc3N1bWVzIHRoYXQgdGhlIHByZWRpY3RvcnMgYXJlIG5vdCBoaWdobHkgY29ycmVsYXRlZCB3aXRoIGVhY2ggb3RoZXIuIAoKLSAqKk5vIEZld2VyIHRoYW4gMTAgT2JzZXJ2YXRpb25zIHBlciBQcmVkaWN0b3IqKiBhc3N1bWVzIHRoYXQgdGhlcmUgYXJlIGF0IGxlYXN0IDEwIG9ic2VydmF0aW9ucyBmb3IgZWFjaCBwcmVkaWN0b3IgaW4gdGhlIG1vZGVsLgoKSW4gb3VyIGZpcnN0IGFzc2lnbm1lbnQsIHdlIHVzZWQgT0xTIHJlZ3Jlc3Npb24gdG8gYWNjZXNzIGhvdyB2YWNhbmN5IHJhdGVzLCBzaW5nbGUtZmFtaWx5IGhvdXNpbmcgcGVyY2VudGFnZSwgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCwgYW5kIHBvdmVydHkgcmF0ZXMgaW5mbHVlbmNlIG1lZGlhbiBob3VzZSB2YWx1ZXMgaW4gUGhpbGFkZWxwaGlhLiBBbGwgcHJlZGljdG9ycyB3ZXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuIFRoZSBtb2RlbCdzIFItc3F1YXJlZCB3YXMgMC42Niwgd2hpY2ggaW5kaWNhdGUgdGhlIG1vZGVsIGV4cGxhaW4gNjYlIG9mIHRoZSB2YXJpYW5jZSBpbiBob3VzZSB2YWx1ZXMuICAKCkhvd2V2ZXIsIHNvbWUgcHJlZGljdG9ycyBleGhpYml0ZWQgbm9uLWxpbmVhciBwYXR0ZXJucywgYW5kIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uIHN1Z2dlc3RlZCBkZXBlbmRlbmNlIGFtb25nIG9ic2VydmF0aW9ucy4gRm9yIE9MUyByZWdyZXNzaW9uLCBvbmUgb2YgdGhlIHZpdGFsIGFzc3VtcHRpb25zIG9mIE9MUyByZWdyZXNzaW9uIGlzIHRoYXQgKipvYnNlcnZhdGlvbnMgYXJlIGluZGVwZW5kZW50IG9mIGVhY2ggb3RoZXIqKi4gSW4gc3BhdGlhbCBkYXRhLCBvYnNlcnZhdGlvbnMgdGhhdCBhcmUgZ2VvZ3JhcGhpY2FsbHkgY2xvc2Ugb2Z0ZW4gZXhoaWJpdCBzaW1pbGFyaXR5LCBsZWFkaW5nIHRvIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uIGFuZCB2aW9sYXRpbmcgdGhlIGluZGVwZW5kZW5jZSBhc3N1bXB0aW9uLiBXaGVuIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uIGlzIHByZXNlbnQsIHZhbHVlcyBvZiBhIHZhcmlhYmxlIGluIG5lYXJieSBhcmVhcyBhcmUgcmVsYXRlZCByYXRoZXIgdGhhbiByYW5kb21seSBkaXN0cmlidXRlZC4gV2UgbmVlZCBmdXJ0aGVyIHRlc3QgdGhlIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uIGFuZCBrZXkgYXNzdW1wdGlvbnMgb2YgT0xTIHJlZ3Jlc3Npb24gaW4gb3JkZXIgdG8gaW1wcm92ZSB0aGUgbW9kZWwncyBhY2N1cmFjeSBhbmQgcmVsaWFiaWxpdHkuIAoKRnVydGhlcm1vcmUsIHdoZW4gZGF0YSBoYXMgYSBzcGF0aWFsIGNvbXBvbmVudCwgdGhlIGFzc3VtcHRpb24gb2YgKipub3JtYWxpdHkgb2YgcmVzaWR1YWxzKiogb2Z0ZW4gZmFpbHMgdG8gaG9sZC4gSW4gc29tZSBjYXNlcywgc3BhdGlhbCBhdXRvY29ycmVsYXRpb24gZG9lcyBub3Qgc2lnbmlmaWNhbnRseSBpbXBhY3QgcmVncmVzc2lvbiBhbmFseXNpcy4gSWYgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSBleGhpYml0cyBzdHJvbmcgc3BhdGlhbCBhdXRvY29ycmVsYXRpb24gd2hpbGUgdGhlIGVycm9yIHRlcm0gZG9lcyBub3QsIHRoZSByZWdyZXNzaW9uIGNvZWZmaWNpZW50cyBhbmQgc2lnbmlmaWNhbmNlIGxldmVscyByZW1haW4gdmFsaWQuIEFkZGl0aW9uYWxseSwgaWYgYm90aCB0aGUgZGVwZW5kZW50IGFuZCBpbmRlcGVuZGVudCB2YXJpYWJsZXMgc2hhcmUgYW4gaWRlbnRpY2FsIHNwYXRpYWwgcGF0dGVybiwgYW5kIHRoZSBzcGF0aWFsIGRlcGVuZGVuY2llcyBpbiB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIGFyZSBmdWxseSBleHBsYWluZWQgYnkgdGhvc2UgaW4gdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlLCB0aGUgcmVzaWR1YWxzIG1heSBiZSBzcGF0aWFsbHkgaW5kZXBlbmRlbnQuIEhvd2V2ZXIsIHRoaXMgaXMgbm90IGFsd2F5cyB0aGUgY2FzZSwgYW5kICoqaXQgaXMgZXNzZW50aWFsIHRvIHRlc3QgZm9yIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uIGluIHJlc2lkdWFscyB0byBlbnN1cmUgdGhlIHZhbGlkaXR5IG9mIHRoZSBtb2RlbCoqLgoKCiMjIyBUZXN0IGZvciBTcGFyaWFsIEF1dG9jb3JyZWxhdGlvbgoKVG8gdGVzdCB0aGlzIGFzc3VtcHRpb24sIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uIG9mIHRoZSByZXNpZHVhbHMgY2FuIGJlIGV4YW1pbmVkIHVzaW5nICoqTW9yYW7igJlzIEkqKiwgd2hpY2ggbWVhc3VyZXMgd2hldGhlciByZXNpZHVhbHMgYXJlIGNsdXN0ZXJlZCwgZGlzcGVyc2VkLCBvciByYW5kb21seSBkaXN0cmlidXRlZCBpbiBzcGFjZS4gQXMgbWVudGlvbmVkIGJlZm9yZSwgaXQgaXMgZmlyc3QgZXh0cmFjdCB0aGUgcmVzaWR1YWxzIGFuZCBkZWZpbmUgYSBzcGF0aWFsIHdlaWdodHMgbWF0cml4IChlLmcuLCBRdWVlbiBvciBSb29rIGNvbnRpZ3VpdHkpLiBUaGVuLCBNb3JhbuKAmXMgSSBpcyBjb21wdXRlZCB0byBtZWFzdXJlIHRoZSBkZWdyZWUgb2YgY2x1c3RlcmluZyBpbiByZXNpZHVhbHMsIHdpdGggdmFsdWVzIGNsb3NlIHRvICsxIGluZGljYXRpbmcgcG9zaXRpdmUgc3BhdGlhbCBhdXRvY29ycmVsYXRpb24sIC0xIGluZGljYXRpbmcgbmVnYXRpdmUgYXV0b2NvcnJlbGF0aW9uLCBhbmQgMCBzdWdnZXN0aW5nIHJhbmRvbW5lc3MuCgpBbm90aGVyIG1ldGhvZCB0byB0ZXN0IGZvciBzcGF0aWFsIGF1dG9jb3JyZWxhdGlvbiBpbiBPTFMgcmVzaWR1YWxzIGlzIHRvICoqcmVncmVzcyB0aGVtIG9uIHRoZSByZXNpZHVhbHMgZnJvbSBuZWFyYnkgb2JzZXJ2YXRpb25zKiouIEluIHRoaXMgcmVwb3J0LCBuZWFyYnkgcmVzaWR1YWxzIHJlZmVyIHRvIHJlc2lkdWFscyBmcm9tIG5laWdoYm9yaW5nIGJsb2NrIGdyb3VwcywgYXMgZGVmaW5lZCBieSB0aGUgUXVlZW4gbWF0cml4LiBUaGUgcmVncmVzc2lvbiBsaW5lIGJldHdlZW4gdGhlIHJlc2lkdWFscywgYE9MU19SRVNJRFVgIGFuZCBgV1RfUkVTSURVYCAod2VpZ2h0ZWQgcmVzaWR1YWxzIGZyb20gbmVpZ2hib3JpbmcgZ3JvdXBzKSwgaGVscCBpZGVudGlmeSBhbnkgc3BhdGlhbCBhdXRvY29ycmVsYXRpb24uIFRoZSAqKnNsb3BlIChiKSoqIG9mIHRoaXMgcmVncmVzc2lvbiByZXByZXNlbnRzIHRoZSBzdHJlbmd0aCBvZiBzcGF0aWFsIGRlcGVuZGVuY2UuIEl0IGlzIGNhbGN1bGF0ZWQgYnkgZXN0aW1hdGluZyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHJlc2lkdWFscyBvZiBvbmUgb2JzZXJ2YXRpb24gYW5kIHRob3NlIG9mIGl0cyBuZWlnaGJvcnMuCgotIElmICoqYj4wKiosIHRoZXJlIGlzIHBvc2l0aXZlIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uLCBtZWFuaW5nIGFyZWFzIHdpdGggaGlnaCByZXNpZHVhbHMgdGVuZCB0byBiZSBuZWFyIG90aGVyIGFyZWFzIHdpdGggaGlnaCByZXNpZHVhbHMgKG9yIGxvdyBuZWFyIGxvdykuCi0gSWYgKipiPDAqKiwgdGhlcmUgaXMgbmVnYXRpdmUgc3BhdGlhbCBhdXRvY29ycmVsYXRpb24sIG1lYW5pbmcgYXJlYXMgd2l0aCBoaWdoIHJlc2lkdWFscyBhcmUgc3Vycm91bmRlZCBieSBhcmVhcyB3aXRoIGxvdyByZXNpZHVhbHMgKGFuZCB2aWNlIHZlcnNhKS4KLSBJZiAqKmLiiYgwKiosIHRoZXJlIGlzIG5vIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uLCBzdWdnZXN0aW5nIHRoYXQgdGhlIHJlc2lkdWFscyBhcmUgcmFuZG9tbHkgZGlzdHJpYnV0ZWQuCgojIyMgQXNzdW1wdGlvbnMgVGVzdAoKSW4gUiwgdGhlcmUgYXJlIG1ldGhvZHMgdG8gdGVzdCBvdGhlciBrZXkgYXNzdW1wdGlvbiBhcyB3ZWxsLiBXZSB3aWxsIGNvbnRpbnVlIHVzaW5nIFIgZm9yIHRoZSBhbmFseXNpcy4KCkFub3RoZXIga2V5IGFzc3VtcHRpb24gaXMgKipIb21vc2NlZGFzdGljaXR5KiosIHdoaWNoIGFhc3N1bWUgdGhhdCB0aGUgdmFyaWFuY2Ugb2YgdGhlIGVycm9ycyAocmVzaWR1YWxzKSByZW1haW5zIGNvbnN0YW50IGFjcm9zcyBhbGwgbGV2ZWxzIG9mIHRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZXMuIEluIFIsIHdlIHVzZWQgICoqQnJldXNjaC1QYWdhbiBUZXN0KiosICoqS29lbmtlci1CYXNzZXR0IFRlc3QqKihhbHNvIGtub3duIGFzIHRoZSBTdHVkZW50aXplZCBCcmV1c2NoLVBhZ2FuIFRlc3QpLiBhbmQgKipXaGl0ZSBUZXN0KiogIHRvIGRldGVjdCBoZXRlcm9zY2VkYXN0aWNpdHkuCgotICoqTnVsbCBoeXBvdGhlc2lzIChI4oKAKToqKiBUaGUgZXJyb3JzIGhhdmUgY29uc3RhbnQgdmFyaWFuY2UgKGhvbW9zY2VkYXN0aWNpdHkpLgotICoqQWx0ZXJuYXRpdmUgaHlwb3RoZXNpcyAoSOKCgSk6KiogVGhlIGVycm9ycyBoYXZlIG5vbi1jb25zdGFudCB2YXJpYW5jZSAoaGV0ZXJvc2NlZGFzdGljaXR5KS4KCklmIHRoZSBwLXZhbHVlIGlzIGxlc3MgdGhhbiAwLjA1LCB0aGVuIHdlIGNhbiByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBmb3IgdGhlIGFsdGVybmF0ZSBoeXBvdGhlc2lzIG9mCmhldGVyb3NjZWRhc3RpY2l0eS4KCkFub3RoZXIgYXNzdW1wdGlvbiBpcyAqKk5vcm1hbGl0eSBvZiBFcnJvcnMqKiwgd2hpY2ggYXNzdW1lcyB0aGF0IHJlc2lkdWFscyBmb2xsb3cgYSBub3JtYWwgZGlzdHJpYnV0aW9u4oCUYSBjcnVjaWFsIHJlcXVpcmVtZW50IGZvciB2YWxpZCBoeXBvdGhlc2lzIHRlc3RpbmcgYW5kIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLiBJbiBSLCB3ZSB1c2VkICoqSmFycXVlLUJlcmEgVGVzdCAqKi4KCi0gKipOdWxsIGh5cG90aGVzaXMgKEjigoApOioqIFRoZSByZXNpZHVhbHMgZm9sbG93IGEgbm9ybWFsIGRpc3RyaWJ1dGlvbi4KLSAqKkFsdGVybmF0aXZlIGh5cG90aGVzaXMgKEjigoEpOioqIFRoZSByZXNpZHVhbHMgZG8gbm90IGZvbGxvdyBhIG5vcm1hbCBkaXN0cmlidXRpb24uCgpUaGUgcC12YWx1ZSBkZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHJlc2lkdWFscyBmb2xsb3cgYSBub3JtYWwgZGlzdHJpYnV0aW9uLiBJZiB0aGUgcC12YWx1ZSBpcyBsZXNzIHRoYW4gMC4wNSwgdGhlbiB3ZSBjYW4gcmVqZWN0IHRoZSBOdWxsIEh5cG90aGVzaXMgb2Ygbm9ybWFsaXR5IGZvciB0aGUgYWx0ZXJuYXRpdmUgaHlwb3RoZXNpcyBvZiBub24tbm9ybWFsaXR5LgoKCiMjIFNwYXRpYWwgTGFnIGFuZCBTcGF0aWFsIEVycm9yIFJlZ3Jlc3Npb24KCkluIHRoaXMgcmVwb3J0LCB3ZSBhbHNvIHVzZSBSIHRvIHJ1biBzcGF0aWFsIGxhZyBhbmQgc3BhdGlhbCBlcnJvciByZWdyZXNzaW9ucy4gU3BhdGlhbCBsYWcgcmVncmVzc2lvbiBhc3N1bWVzIHRoZSB2YWx1ZSBvZiB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIGF0IG9uZSBsb2NhdGlvbiBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIHZhbHVlcyBvZiB0aGF0IHZhcmlhYmxlIGluIG5lYXJieSBsb2NhdGlvbnMsIGRlZmluZWQgYnkgd2VpZ2h0cyBtYXRyaXggXChXXCksIHdoZXRoZXIgcm9vaywgcXVlZW4gbmVpZ2hib3JzLCBvciB3aXRoaW4gY2VydGFpbiBkaXN0YW5jZSBvZiBvbmUgYW5vdGhlci4gSW4gb3VyIGNvbnRleHQsIHRoZSBzcGF0aWFsIGxhZyBtb2RlbCBpcyBkZWZpbmVkIGFzIGZvbGxvd3M6CgokJApcdGV4dHtMTk1FREhWQUx9ID0gXHJobyBXIFx0aW1lcyBcdGV4dHtMTk1FREhWQUx9ICsgXGJldGFfMCArIFxiZXRhXzEgXHRpbWVzIFx0ZXh0e1BDVFZBQ0FOVH0gKyBcYmV0YV8yIFx0aW1lcyBcdGV4dHtQQ1RTSU5HTEVTfSArIFxiZXRhXzMgXHRpbWVzIFx0ZXh0e1BDVEJBQ0hNT1J9ICsgXGJldGFfNCBcdGltZXMgXHRleHR7TE5OQkVMUE9WMTAwfSArIFxlcHNpbG9uX2kKJCQKd2hlcmU6CgotIFwoXHRleHR7TE5NRURIVkFMfVwpIGlzIHRoZSBsb2dnZWQgbWVkaWFuIGhvdXNlIHZhbHVlLAotICRccmhvJCBpcyB0aGUgc3BhdGlhbCBhdXRvcmVncmVzc2l2ZSBjb2VmZmljaWVudCwgd2hpY2ggbWVhc3VyZXMgdGhlIGluZmx1ZW5jZSBvZiBuZWlnaGJvcmluZyBhcmVhcyBvbiB0aGUgbWVkaWFuIGhvdXNlIHZhbHVlLAotIFwoV1wpIGlzIHRoZSBzcGF0aWFsIHdlaWdodHMgbWF0cml4IChpbiB0aGlzIGNhc2UsIHRoZSBRdWVlbiBzcGF0aWFsIG1hdHJpeCksCi0gJFcgXHRpbWVzIFx0ZXh0e0xOTUVESFZBTH0kIGlzIHRoZSBzcGF0aWFsbHkgbGFnZ2VkIGRlcGVuZGVudCB2YXJpYWJsZSAoaG91c2UgcHJpY2UpLAoKVGhlIG90aGVyIHRlcm0gYXJlIHNhbWUgYXMgaW4gdGhlIE9MUyByZWdyZXNzaW9uIG1vZGVsLCB3aGVyZToKCi0gXChcYmV0YV8wXCkgaXMgdGhlIGludGVyY2VwdCwKLSBcKFxiZXRhXzFcKSwgXChcYmV0YV8yXCksIFwoXGJldGFfM1wpLCBhbmQgXChcYmV0YV80XCkgYXJlIHRoZSBjb2VmZmljaWVudHMgb2YgdGhlIHByZWRpY3RvcnMsCi0gXChcZXBzaWxvbl9pXCkgaXMgdGhlIGVycm9yIHRlcm0uCgpUaGUgc3BhdGlhbCBlcnJvciBtb2RlbCwgb24gdGhlIG90aGVyIGhhbmQsIGFzc3VtZXMgdGhhdCB0aGUgcmVzaWR1YWxzIG9mIHRoZSBtb2RlbCBhcmUgc3BhdGlhbGx5IGF1dG9jb3JyZWxhdGVkLkl0IGFzc3VtZXMgdGhhdCB0aGUgcmVzaWR1YWwgaW4gb25lIGxvY2F0aW9uIGlzIGFzc29jaWF0ZWQgd2l0aCByZXNpZHVhbHMgYXQgbmVhcmJ5IGxvY2F0aW9ucyBkZWZpbmVkIGJ5IHRoZSBzcGF0aWFsIHdlaWdodHMgbWF0cml4IFwoV1wpLCBpbiB0aGlzIGNhc2UgdGhlIHF1ZWVuIHNwYXRpYWwgbWF0cml4LiBUaGUgc3BhdGlhbCBlcnJvciBtb2RlbCBpcyBkZWZpbmVkIGFzIGZvbGxvd3M6CgokJApcdGV4dHtMTk1FREhWQUx9ID0gXGJldGFfMCArIFxiZXRhXzEgXHRpbWVzIFx0ZXh0e1BDVFZBQ0FOVH0gKyBcYmV0YV8yIFx0aW1lcyBcdGV4dHtQQ1RTSU5HTEVTfSArIFxiZXRhXzMgXHRpbWVzIFx0ZXh0e1BDVEJBQ0hNT1J9ICsgXGJldGFfNCBcdGltZXMgXHRleHR7TE5OQkVMUE9WMTAwfSArIFxsYW1iZGEgVyBcdGltZXMgXGVwc2lsb24gKyB1CiQkCgp3aGVyZToKCi0gXChcbGFtYmRhXCkgaXMgdGhlIHNwYXRpYWwgZXJyb3IgY29lZmZpY2llbnQgd2hpY2ggbWVhc3VyZSB0aGUgZGVncmVlIG9mIHNwYXRpYWwgY29ycmVsYXRpb24gaW4gdGhlIGVycm9yIHRlcm0sCi0gXChXXCkgaXMgdGhlIHNwYXRpYWwgd2VpZ2h0cyBtYXRyaXggKGluIHRoaXMgY2FzZSwgdGhlIFF1ZWVuIHNwYXRpYWwgbWF0cml4KSwKLSBcKFcgXHRpbWVzIFxlcHNpbG9uXCkgaXMgdGhlIHNwYXRpYWxseSBsYWdnZWQgZXJyb3IgdGVybSwKLSBcKCB1IFwpIGlzIHRoZSByYW5kb20gbm9pc2UgdGVybS4KClRoZSBvdGhlciB0ZXJtIGlzIHRoZSBzYW1lIGFzIGluIHRoZSBPTFMgcmVncmVzc2lvbiBtb2RlbCwgd2hlcmU6CgotIFwoXHRleHR7TE5NRURIVkFMfVwpIGlzIHRoZSBsb2dnZWQgdHJhbnNmb3JtZWQgIG1lZGlhbiBob3VzZSB2YWx1ZSwKLSBcKFxiZXRhXzBcKSBpcyB0aGUgaW50ZXJjZXB0LAotIFwoXGJldGFfMVwpLCBcKFxiZXRhXzJcKSwgXChcYmV0YV8zXCksIGFuZCBcKFxiZXRhXzRcKSBhcmUgdGhlIGNvZWZmaWNpZW50cyBvZiB0aGUgcHJlZGljdG9ycy4KCkJvdGggc3BhdGlhbCBlcnJvciByZWdyZXNzaW9uIGFuZCBzcGF0aWFsIGxhZyByZWdyZXNzaW9uIHJlcXVpcmUgc3RhbmRhcmQgYXNzdW1wdGlvbnMgb2YgT0xTIHJlZ3Jlc3Npb24sIGluY2x1ZGluZyBsaW5lcmFyaXR5LCBob21vc2NlZGFzdGljaXR5LCBhbmQgbm9ybWFsaXR5IG9mIHJlc2lkdWFscywgZXhjZXB0eSBmb3IgdGhlIGFzc3VtcHRpb25zIG9mIHNwYXRpYWwgaW5kZXBlbmRlbmNlIGFtb25nIG9ic2VydmF0aW9ucy4gVGhpcyBhZGp1c3RtZW50IGFsbG93cyB0aGUgbW9kZWwgdG8gYWNjb3VudCBmb3Igc3BhdGlhbCBhdXRvY29ycmVsYXRpb24gYW5kIHNwYXRpYWwgaGV0ZXJvZ2VuZWl0eSBpbiB0aGUgZGF0YSB0aHJvdWdoIGVpdGhlciB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIChzcGF0aWFsIGxhZyBtb2RlbCkgb3IgdGhlIGVycm9yIHRlcm0gKHNwYXRpYWwgZXJyb3IgbW9kZWwpLiBUaGVzZSB0d28gbW9kZWxzIG1pbmltaXplIHNwYXRpYWwgcGF0dGVybnMgaW4gcmVzaWR1YWxzIHRoYXQgY291bGQgbGVhZCB0byBiaWFzZWQgYW5kIGluZWZmaWNpZW50IGVzdGltYXRlcy4KCldlIGNvbXBhcmUgdGhlIHJlc3VsdHMgb2Ygc3BhdGlhbCBsYWcgYW5kIHNwYXRpYWwgZXJyb3IgcmVncmVzc2lvbiB3aXRoIHRoZSBPTFMgcmVncmVzc2lvbiB0byBkZWNpZGUgd2hldGhlciB0aGUgdHdvIHNwYXRpYWwgbW9kZWxzIHBlcmZvcm0gYmV0dGVyIHRoYW4gT0xTIHJlZ3Jlc3Npb24gYmFzZWQgb24gc2V2ZXJhbCBjcml0ZXJpYTogQWthaWtlIEluZm9ybWF0aW9uIENyaXRlcmlvbiAoQUlDKSwgU2Nod2FyeiBDcml0ZXJpb24gKFNDLCBhbHNvIGtub3duIGFzIEJheWVzaWFuIEluZm9ybWF0aW9uIENyaXRlcmlvbiwgQklDKSwgTG9nIGxpa2VsaWhvb2QsIGFuZCBsaWtlbGlob29kIHJhdGlvIHRlc3QuCgpUaGUgKipBa2Fpa2UgSW5mb3JtYXRpb24gQ3JpdGVyaW9uIChBSUMpKiogYW5kICoqU2Nod2FyZCBDcml0ZXJpb24gKFNDIG9yIEJJQykqKiBhcmUgdXNlZCB0byBjb21wYXJlZCB0aGUgbW9kZWwncyBnb29kbmVzcyBvZiBmaXQuIFRoZXkgd29yayBieSBlc3RpbWF0aW5nIGhvdyBtdWNoIGluZm9ybWF0aW9uIGlzIGxvc3Qgd2hlbiBhIG1vZGVsIGlzIHVzZWQgdG8gcmVwcmVzZW50IHJlYWxpdHkuIEVzc2VudGlhbGx5LCB0aGV5IGJhbGFuY2UgaG93IGFjY3VyYXRlIHRoZSBtb2RlbCBpcyBhZ2FpbnN0IGhvdyBjb21wbGljYXRlZCBpdCBpcy4gQSBsb3dlciBBSUMgb3IgU0Mgc2NvcmUgbWVhbnMgdGhlIG1vZGVsIGRvZXMgYSBiZXR0ZXIgam9iIGF0IHRoaXMgYmFsYW5jZS4KClRoZSAqKkxvZyBsaWtlbGlob29kKiogaXMgYSBtZWFzdXJlIHVzZWQgaW4gdGhlIG1heGltdW0gbGlrZWxpaG9vZCBmb3IgZml0dGluZyBhIHN0YXRpc3RpY2FsIG1vZGVsIHRvIHRoZSBkYXRhIGFuZCBlc3RpbWF0aW5nIG1vZGVsIHBhcmFtZXRlcnMuIE1heGltdW0gbGlrZWxpaG9vZCBwaWNrcyB0aGUgdmFsdWVzIG9mIHRoZSBwYXJhbWV0ZXJzIHRoYXQgbWFrZSB0aGUgb2JzZXJ2ZWQgZGF0YSBhcyBsaWtlbHkgYXMgcG9zc2libGUuIFRoZSBoaWdoZXIgdGhlIGxvZyBsaWtlbGlob29kLCB0aGUgYmV0dGVyIHRoZSBtb2RlbCBleHBsYWlucyB0aGUgZGF0YS4KClRoZSAqKkxpa2VsaWhvb2QgUmF0aW8gVGVzdCoqIGlzIHVzZWQgdG8gdGVzdCB3aGV0aGVyIGFkZGluZyBhIHNwYXRpYWwgZGVwZW5kZW5jZSB0byBhIG1vZGVsIChzcGF0aWFsIGxhZyBvciBzcGF0aWFsIGVycm9yIG1vZGVsKSBzaWduaWZpY2FudGx5IGltcHJvdmVzIHRoZSBtb2RlbCdzIGZpdCBjb21wYXJlZCB0byB0aGUgT0xTIG1vZGVsLiBGb3IgdGhpcyB0ZXN0OgoKLSBUaGUgbnVsbCBoeXBvdGhlc2lzIChcKEhfMFwpKSBzdGF0ZSB0aGF0IHRoZSBzcGF0aWFsIG1vZGVsICBkb2VzIG5vdCBwcm92aWRlIGEgc2lnbmlmaWNhbnQgYmV0dGVyIGZpdCB0aGFuIE9MUwotIFRoZSBhbHRlcm5hdGl2ZSBoeXBvdGhlc2lzIChcKEhfYVwpKSBzdGF0ZSB0aGF0ICB0aGF0IHNwYXRpYWwgbW9kZWwgcHJvdmlkZXMgYSBzaWduaWZpY2FudGx5IGJldHRlciBmaXQgdGhhbiBPTFMuCgpUbyByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBmb3IgdGhlIGFsdGVybmF0aXZlIGh5cG90aGVzaXMgdGhhdCB0aGUgc3BhdGlhbCBtb2RlbCBwcm92aWRlcyBhIHNpZ25pZmljYW50bHkgYmV0dGVyIGZpdCB0aGFuIE9MUywgdGhlICoqTGlrZWxpaG9vZCBSYXRpbyBUZXN0Kiogc2hvdWxkIGhhdmUgYSBwLXZhbHVlIGlzIGxlc3MgdGhhbiBzaWduaWZpY2FudCBsZXZlbCwgdHlwaWNhbGx5IDAuMDUuIFRoZW4sIHdlIGNhbiBkcmF3IHRoZSBjb25jbHVzaW9uIHdoZXRoZXIgdGhlIHNwYXRpYWwgbW9kZWwgaXMgYmV0dGVyIHRoYW4gT0xTIG1vZGVsLiBJZiBub3QsIHRoZSBPTFMgbW9kZWwgaXMgYWRlcXVhdGUuIAoKKk5vdGU6IHRoZSBsaWtlbGlob29kIHJhdGlvIHRlc3QgaXMgbm90IHVzZWQgdG8gY29tcGFyZSB0aGUgc3BhdGlhbCBsYWcgYW5kIHNwYXRpYWwgZXJyb3IgbW9kZWwsIGJ1dCB0byBjb21wYXJlIHRoZSBzcGF0aWFsIG1vZGVsIHdpdGggdGhlIE9MUyBtb2RlbC4gVGhlIExpa2VsaWhvb2QgUmF0aW8gdGVzdCBvbmx5IHdvcmsgaWYgY29tcGFyZWQgYmV0d2VlbiBuZXN0ZWQgbW9kZWxzLCBtZWFuaW5nIHRoYXQgb25lIG1vZGVsIGlzIHNpbXBsaWZpZWQgdmVyc2lvbiBvZiBvdGhlciAtLSBjb21wbGljYXRlZCBtb2RlbCBjb250YWlucyBhbGwgdGhlIHNhbWUgcGFydHMgYXMgdGhlIHNpbXBsZXIgbW9kZWwsIHBsdXMgZXh0cmEgcGllY2VzLiBUaGUgc3BhdGlhbCBsYWcgbW9kZWwgYW5kIHNwYXRpYWwgZXJyb3IgbW9kZWwgaXMgbm90IGluIHRoYXQgY2FzZS4qCgpBbHRlcm5hdGl2ZWx5LCB3ZSBjYW4gYWxzbyBjb21wYXJlIHRoZSBzcGF0aWFsIG1vZGVscyB0byBPTFMgdXNpbmcgdGhlIE1vcmFuJ3MgSSBzdGF0aXN0aWMsd2hpY2ggbWVhc3VyZXMgdGhlIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uIG9mIHRoZSByZXNpZHVhbHMuIE1vcmFu4oCZcyBJIHJhbmdlcyBmcm9tIC0xIHRvIDEsIHdoZXJlIC0xIGluZGljYXRlcyBwZXJmZWN0IGRpc3BlcnNpb24sIDAgaW5kaWNhdGVzIG5vIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uLCBhbmQgMSBpbmRpY2F0ZXMgcGVyZmVjdCBjb3JyZWxhdGlvbi4gT3VyIGdvYWxzIG9mIHVzaW5nIHNwYXRpYWwgbW9kZWwgaXMgdG8gbWluaW1pemUgdGhlIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uIG9mIHRoZSByZXNpZHVhbHMuIElmIHRoZSBNb3JhbidzIEkgb2YgdGhlIHJlc2lkdWFscyBvZiB0aGUgc3BhdGlhbCBtb2RlbCBpcyBjbG9zZXIgdG8gMCB0aGFuIHRoZSBNb3JhbidzIEkgb2YgdGhlIHJlc2lkdWFscyBvZiB0aGUgT0xTIG1vZGVsLCB0aGVuIHRoZSBzcGF0aWFsIG1vZGVsIGlzIGJldHRlciBhdCBtaW5pbWl6aW5nIHNwYXRpYWwgYXV0b2NvcnJlbGF0aW9uLiBXZSBjYW4gY29uY2x1ZGUgdGhhdCB0aGUgc3BhdGlhbCBtb2RlbCBpcyBiZXR0ZXIgY2FwdHVyZXMgdGhlIHNwYXRpYWwgZGVwZW5kZW5jaWVzIGluIHRoZSBkYXRhIHRoYW4gdGhlIE9MUyBtb2RlbC4KCiMjIEdlb2dyYXBoaWNhbGx5IFdlaWdodGVkIFJlZ3Jlc3Npb24KCgoKCiMgUmVzdWx0cwoKIyMgU3BhdGlhbCBBdXRvY29ycmVsYXRpb24KCiMjIEEgUmV2aWV3IG9mIE9MUyBSZWdyZXNzaW9uIGFuZCBBc3N1bXB0aW9uczogUmVzdWx0cwoKCiMjIFNwYXRpYWwgTGFnIGFuZCBTcGF0aWFsIEVycm9yIFJlZ3Jlc3Npb24gUmVzdWx0cwoKCiMjIEdlb2dyYXBoaWNhbGx5IFdlaWdodGVkIFJlZ3Jlc3Npb24gUmVzdWx0c+OAgQoKCgojIERpc2N1c3Npb24KCmBgYHtyfQojIGEuIHJlY3JlYXRlIHZhcmlhYmxlCmRhdGE8LWRhdGElPiUKICBtdXRhdGUoTE5OQkVMUE9WMTAwID0gbG9nKDErTkJlbFBvdjEwMCkpCmBgYAoKYGBge3IgY29uc3RydWN0IHF1ZWVuIG5laWdoYm9ycywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KCnF1ZWVuPC1wb2x5Mm5iKGRhdGEsIHJvdy5uYW1lcz1kYXRhJFBPTFlfSUQpCnF1ZWVubGlzdDwtbmIybGlzdHcocXVlZW4sIHN0eWxlID0gJ1cnKQoKYGBgCgoKYGBge3IgZ2xvYmFsIG1vcmFuIEksIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgpnbG9iYWxtb3Jhbk1DPC1tb3Jhbi5tYyhkYXRhJExOTUVESFZBTCwgcXVlZW5saXN0LCBuc2ltPTk5OSwgYWx0ZXJuYXRpdmU9InR3by5zaWRlZCIpIApnbG9iYWxtb3Jhbk1DCmBgYAoKYGBge3IgZ2xvYmFsIG1vcmFuIGhpc3RvZ3JhbSBwbG90LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKZ2dwbG90KGRhdGEuZnJhbWUocmVzID0gZ2xvYmFsbW9yYW5NQyRyZXMpLCBhZXMoeCA9IHJlcykpICsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTAwLCBmaWxsID0gIiMyODNkM2IiKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gZ2xvYmFsbW9yYW5NQyRzdGF0aXN0aWMsIGNvbG9yID0gIiNjNDQ1MzYiLCBsaW5ldHlwZSA9ICdkYXNoZWQnLCBzaXplID0gMSkgKwogIGxhYnModGl0bGUgPSAiT2JzZXJ2ZWQgYW5kIFBlcm11dGVkIEdsb2JhbCBNb3JhbidzIEkiLAogICAgICAgc3VidGl0bGUgPSAiT2JzZXJ2ZWQgTW9yYW4ncyBJIGluIFJlZCIsCiAgICAgICB4ID0gIk1vcmFuJ3MgSSIsCiAgICAgICB5ID0gIkNvdW50IikgKwogIHRoZW1lX2xpZ2h0KCkgKyAgIAogIHRoZW1lKHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDksZmFjZSA9ICJpdGFsaWMiKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJib2xkIiksIAogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPTYpLAogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTYpLCAKICAgICAgICBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTgpKQoKYGBgCgpgYGB7ciBnbG9iYWwgbW9yYW4gc2NhdHRlciBwbG90LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpkYXRhMSA8LSBkYXRhLmZyYW1lKCBMTk1FREhWQUwgPSBkYXRhJExOTUVESFZBTCwgc3BhdGlhbF9sYWcgPSBsYWcubGlzdHcocXVlZW5saXN0LCBkYXRhJExOTUVESFZBTCkpCgpnZ3Bsb3QoZGF0YTEsIGFlcyh4ID0gTE5NRURIVkFMLCB5ID0gc3BhdGlhbF9sYWcpKSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICIjMjgzZDNiIiwgYWxwaGEgPSAwLjcsIHNpemUgPSAwLjYpICsgIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbG9yID0gIiNjNDQ1MzYiLCBzZSA9IEZBTFNFKSArIAogIGxhYnModGl0bGUgPSAiR2xvYmFsIE1vcmFuJ3MgSSBTY2F0dGVyIFBsb3QiLAogICAgICAgeCA9ICJMb2dnZWQgTWVkaWFuIEhvdXNlIFZhbHVlIiwKICAgICAgIHkgPSAiU3BhdGlhbCBMYWcgb2YgTE5NRURIVkFMIikgKwogIHRoZW1lX2xpZ2h0KCkgKyAgIAogIHRoZW1lKHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDksZmFjZSA9ICJpdGFsaWMiKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJib2xkIiksIAogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPTYpLAogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTYpLCAKICAgICAgICBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTgpKQpgYGAKCgpgYGB7cn0KIyBkLiBMb2NhbCBNb3JhbidzIEkgKExJU0EgYW5hbHlzaXMpIGZvciBMTk1FSFZBTApsbW9yYW48LWxvY2FsbW9yYW4oZGF0YSRMTk1FREhWQUwsIHF1ZWVubGlzdCkKaGVhZChsbW9yYW4pCmBgYAoKYGBge3J9CmRmLmxtb3JhbiA8LWNiaW5kKGRhdGEsIGFzLmRhdGEuZnJhbWUobG1vcmFuKSkKYGBgCgoKYGBge3J9CnRtYXBfbW9kZSgicGxvdCIpCgojT2J0YWluaW5nIHRoZSBMb2NhbCBNb3JhbidzIFAtVmFsdWVzICh0d28tc2lkZWQpCmRhdGEkbG1wIDwtIGxtb3JhblssICJQcih6ICE9IEUoSWkpKSJdCgpkYXRhIDwtIHN0X21ha2VfdmFsaWQoZGF0YSkKCgojQ3JlYXRpbmcgdGhlIExJU0EgQ2x1c3RlcnMKbXAgPC0gbW9yYW4ucGxvdChhcy52ZWN0b3Ioc2NhbGUoZGF0YSRMTk1FREhWQUwpKSwgcXVlZW5saXN0KQpgYGAKCmBgYHtyfQojU2lnbmlmaWNhbmNlIE1hcCBhbmQgQ2x1c3RlciBNYXAKCmRhdGEkcXVhZHJhbnQgPC0gTkEKIyBoaWdoLWhpZ2gKZGF0YVsobXAkeCA+PSAwICYgbXAkd3ggPj0gMCkgJiAoZGF0YSRsbXAgPD0gMC4wNSksICJxdWFkcmFudCJdPC0gMQojIGxvdy1sb3cKZGF0YVsobXAkeCA8PSAwICYgbXAkd3ggPD0gMCkgJiAoZGF0YSRsbXAgPD0gMC4wNSksICJxdWFkcmFudCJdPC0gMgojIGhpZ2gtbG93CmRhdGFbKG1wJHggPj0gMCAmIG1wJHd4IDw9IDApICYgKGRhdGEkbG1wIDw9IDAuMDUpLCAicXVhZHJhbnQiXTwtIDMKIyBsb3ctaGlnaApkYXRhWyhtcCR4IDw9IDAgJiBtcCR3eCA+PSAwKSAmIChkYXRhJGxtcCA8PSAwLjA1KSwgInF1YWRyYW50Il08LSA0CiMgbm9uLXNpZ25pZmljYW50CmRhdGFbKGRhdGEkbG1wID4gMC4wNSksICJxdWFkcmFudCJdIDwtIDUKCgojIExJU0EgUC1WYWx1ZSBNYXAKcF92YWxzIDwtIHRtX3NoYXBlKGRhdGEpICsKICB0bV9wb2x5Z29ucyhjb2wgPSAibG1wIiwgdGl0bGUgPSAiIiwKICAgICAgICAgICAgICBicmVha3MgPSBjKC1JbmYsIDAuMDAxLCAwLjAxLCAwLjA1LCBJbmYpLAogICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCJkYXJrYmx1ZSIsICJibHVlIiwgImxpZ2h0Ymx1ZSIsICJ3aGl0ZSIpKSArCiAgdG1fbGF5b3V0KAogICAgbGVnZW5kLm91dHNpZGUgPSBUUlVFLAogICAgbGVnZW5kLnRleHQuc2l6ZSA9IDEsCiAgICBsZWdlbmQudGl0bGUuc2l6ZSA9IDEsCiAgICBmb250ZmFtaWx5ID0gIkFyaWFsIiwKICAgIHRpdGxlID0gIkxJU0EgUC1WYWx1ZSBNYXAiLAogICAgdGl0bGUuc2l6ZSA9IDEuMiwKICAgIGZyYW1lID0gRkFMU0UKICApCgojIExJU0EgQ2x1c3RlciBNYXAKY2x1c3RlcnMgPC0gdG1fc2hhcGUoZGF0YSkgKwogIHRtX2ZpbGwoY29sID0gInF1YWRyYW50IiwgdGl0bGUgPSAiIiwKICAgICAgICAgIGJyZWFrcyA9IGMoMSwgMiwgMywgNCwgNSwgNiksCiAgICAgICAgICBwYWxldHRlID0gYygicmVkIiwgImJsdWUiLCAibGlnaHRwaW5rIiwgInNreWJsdWUyIiwgIndoaXRlIiksCiAgICAgICAgICBsYWJlbHMgPSBjKCJIaWdoLUhpZ2giLCAiTG93LUxvdyIsICJIaWdoLUxvdyIsICJMb3ctSGlnaCIsICJOb24tc2lnbmlmaWNhbnQiKSkgKwogIHRtX2JvcmRlcnMoYWxwaGEgPSAwLjUpICsKICB0bV9sYXlvdXQoCiAgICBmcmFtZSA9IEZBTFNFLAogICAgbGVnZW5kLm91dHNpZGUgPSBUUlVFLAogICAgbGVnZW5kLnRleHQuc2l6ZSA9IDEsCiAgICBsZWdlbmQudGl0bGUuc2l6ZSA9IDEsCiAgICBmb250ZmFtaWx5ID0gIkFyaWFsIiwKICAgIHRpdGxlID0gIkxJU0EgQ2x1c3RlciBNYXAiLAogICAgdGl0bGUuc2l6ZSA9IDEuMgogICkKCnBfdmFscwoKY2x1c3RlcnMKYGBgCgoKCmBgYHtyfQojIGUuIE9MUyBSZWdyZXNzaW9uIEFuYWx5c2lzCnJlZzwtbG0oTE5NRURIVkFMIH4gTE5OQkVMUE9WK1BDVEJBQ0hNT1IrUENUU0lOR0xFUytQQ1RWQUNBTlQsIGRhdGE9ZGF0YSkKc3VtbWFyeShyZWcpCmBgYAoKYGBge3J9CiMgZy4gIE9MUyByZXNpZHVhbHMgcGxvdHRlZApkYXRhJE9MU19SRVNJRFU8LXJzdGFuZGFyZChyZWcpCmRhdGEkV1RfUkVTSURVPC1zYXBwbHkocXVlZW4sIGZ1bmN0aW9uKHgpIG1lYW4oZGF0YSRPTFNfUkVTSURVW3hdKSkKCk9MUy5SZXNpZHVhbHMuTWFwPC10bV9zaGFwZShkYXRhKSsKICB0bV9maWxsKGNvbD0nT0xTX1JFU0lEVScsIHN0eWxlPSdxdWFudGlsZScsIHRpdGxlPSdTdGFuZGFyZGl6ZWQgT0xTIFJlc2lkdWFscycsCiAgICAgICAgICBwYWxldHRlID0nQmx1ZXMnKSsKICB0bV9sYXlvdXQoZnJhbWU9RkFMU0UsIHRpdGxlID0gJ1N0YW5kYXJkaXNlZCBPTFMgUmVzaWR1YWxzJykKT0xTLlJlc2lkdWFscy5NYXAKYGBgCgoKYGBge3J9CiMgc2NhdHRlcnBsb3Qgb2YgT0xTX1JFU0lEVSBieSBXVF9SRVNJRFUKZ2dwbG90KGRhdGEsIGFlcyh4ID0gV1RfUkVTSURVLCB5ID0gT0xTX1JFU0lEVSkpICsKICBnZW9tX3BvaW50KGNvbG9yID0gImJsdWUiLCBhbHBoYSA9IDAuNikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIpICsKICBsYWJzKHRpdGxlID0gIlNjYXR0ZXIgUGxvdCBvZiBPTFMgUmVzaWR1YWxzIHZzLiBXZWlnaHRlZCBSZXNpZHVhbHMiLAogICAgICAgeCA9ICJXZWlnaHRlZCBSZXNpZHVhbHMgKFdUX1JFU0lEVSkiLAogICAgICAgeSA9ICJPTFMgUmVzaWR1YWxzIChPTFNfUkVTSURVKSIpICsKICB0aGVtZV9taW5pbWFsKCkKCiMgUnVuIHNpbXBsZSByZWdyZXNzaW9uIG9mIE9MU19SRVNJRFUgb24gV1RfUkVTSURVCmxtX3Jlc2lkdWFscyA8LSBsbShPTFNfUkVTSURVIH4gV1RfUkVTSURVLCBkYXRhID0gZGF0YSkKc3VtbWFyeShsbV9yZXNpZHVhbHMpCmBgYAoKCmBgYHtyfQojIGguIE1vcmFu4oCZcyBJIG9mIHRoZSBPTFMgcmVncmVzc2lvbiByZXNpZHVhbHMKCiNSZWdyZXNzaW5nIHJlc2lkdWFscyBvbiB0aGVpciBuZWFyZXN0IG5laWdoYm9ycy4KcmVzLmxtIDwtIGxtKGZvcm11bGE9ZGF0YSRPTFNfUkVTSURVIH4gZGF0YSRXVF9SRVNJRFUpCnN1bW1hcnkocmVzLmxtKQpgYGAKCmBgYHtyfQptb3Jhbi5tYyhkYXRhJE9MU19SRVNJRFUsIHF1ZWVubGlzdCwgOTk5LCBhbHRlcm5hdGl2ZT0idHdvLnNpZGVkIikKYGBgCgpgYGB7cn0KbW9yYW4ucGxvdChkYXRhJE9MU19SRVNJRFUsIHF1ZWVubGlzdCkKYGBgCg==